Angular modal dialog best practices

荒凉一梦 提交于 2019-12-03 14:53:54

Angular UI Boostrap provides a service - $dialog - that can be injected wherever you need to use a dialog box. That service has two main methods: dialog and messageBox. The former is used to create a dialog with dynamic content and the latter to create a message box with a title, a message and a set of buttons. Both return a promise so you can process its result, when it's available.

I think this approach works well, because it fits the somehow natural, imperative way of handling dialogs. For instance, if the user clicks on a button and you want to show a dialog and then process its result, the code could look like this:

$scope.doSomething = function() {
    $dialog.dialog().open().then(function(result) {
       if (result === OK) {
           // Process OK
       }
       else {
           // Process anything else
       }
    });
}

You can indeed use directives to do the same, and perhaps it seems the right way to do it since there is DOM manipulation involved, but I think it would be kind of awkward to handle it. The previous example would be something like this:

<dialog visible="dialogVisible" callback="dialogCallback()"></dialog>

...

$scope.doSomething = function() {   
    $scope.dialogVisible = true; 
}

$scope.dialogCallback = function(result) {
    if (result === OK) {
        // Process OK
    }
    else {
       // Process anything else
    }
}

IMO, the first example looks better and it's easier to understand.

Since dialogs are DOM components, they should probably be directives. You can either build up the DOM elements of the modal inside the directive itself or put the elements on the main html page hidden and unhide them from the directive. If you don't isolate the directive's scope, you can just refer to the controller scope (unless you are in a child scope) from the directive.

Dynamic vs. static content isn't that much of a decision point IMO. Since you have access to the scope from within the directive, you can access whatever you need from the inherited scope.

One quite simple design that works well is to :

  1. Have such a "modal dialog" div somewhere in your html. It will be typically absolute, taking all the screen width and height (typically a dark translucent div with a smaller dialog div into it) and not displayed by default (use ng-show to display it conditionally, depending on the existence of modals or not)
  2. Declare a controller that listens to dialog events ("dialogShow", "dialogClose", etc.) and change its "currentModal" $scope value when receiving them. According to the ng-show condition setup in the previous step, the modal will accordingly display or change or disappear (if set to null/undefined)
  3. Trigger dialog events from anywhere in your application, using broadcasts.

Improvements are:

  • Events parameters properties (setup when triggering and received by the controller) could include title, message, images, even html (to be sanitized), buttons, callbacks for those buttons, display durations (throught $timeout)
  • Remember a stack of received alerts. When one is closed, the next pending one displays
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!