Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular - reusable dialogs

I need to build a dialog to be used with any item on a list of items. The dialog is pretty much the same regardless of the item except for the values of the fields which are obviously item dependent.

The directive I am building is reading the template from a file, compiles it with $compile and then binds (links) it to the scope of the item. The result of the binding is a DOM tree. To make the dialog visible I need to append this tree to some element in the existing DOM. The nature of my dialog is such that it makes sense to append it directly to the body tag. The dialog will be used many times in combination with different items on the list

So here is my question: How much of this process (compile, bind, append) can be done in advance? I certainly can run compile once. I can also bind the compilation result to the $rootscope and append (hidden) it to the body tag. This way I can later just turn on visibility and show the dialog.

But if it is already bound and attached to DOM, is it kosher to re-bind it to some other scope, if so - what's the right way to do it? Another question is is it even worth it? might be just re-insert it every time it is needed?

like image 911
mfeingold Avatar asked Feb 24 '13 03:02

mfeingold


People also ask

What is Mat dialog data?

MatDialog creates modal dialogs that implements the ARIA role="dialog" pattern by default. You can change the dialog's role to alertdialog via MatDialogConfig . You should provide an accessible label to this root dialog element by setting the ariaLabel or ariaLabelledBy properties of MatDialogConfig .


2 Answers

If you're only ever going to display one dialog like that at a time and you will use it frequently, you don't have to re-bind it to another scope, just change the data on the scope. Something like this:

  1. Create a service for your dialog
  2. Create the directive and inject your service into it. When the linking function executes, pass something like $scope.dialogData to the service so that the service can update the data.
  3. Create a controller that gets the service injected. Set the dialog data through the service to display the dialog. Since you're modifying data in your controller that's on the directives scope, Angular notices that and updates your dialog.
  4. Add ng-show on your dialogs wrapper to make it simple to implement open()/close() methods on your service.

Now you have a dialog that can be used from anywhere in your system, and you're just re-using the same directive without having to mess with the DOM or compilation.

like image 139
Anders Ekdahl Avatar answered Nov 15 '22 07:11

Anders Ekdahl


This is indeed excellent question and I'm happy to see that more and more people are starting to approach dialogs as services.

Regarding your particular questions, here are some of my thoughts:

  • You can "cache" linking function (that is - function that is returned from the $compile call) and then call this function as needed (passing in scope variables).
  • Instead of inserting (hidden) compiled element you could only attach it on demand, when a dialog gets opened. On top of this I would rather attach modal element to the $rootElement instead of <body> just not to touch DOM elements above where ng-app was defined. Just not to touch parts of the DOM that AngularJS is not controlling.
  • IMO dialogs are really close to AngularJS routes (as they provide different "views") and as such it would be very nice to have ability to resolve promises before modal is shown (as with routes).

In fact there are number of things to consider when designing a good, generic dialog service and I hope that those advice, alongside with excellent input provided by others, will get you started. But this all is a bit theoretical so if you are looking at the implementation of what was discussed here you can have a look at this implementation. ($dialog service from http://angular-ui.github.com/bootstrap/ - it is fully customizable so can be used with CSS other than Bootstrap's. Documentation here).

It can be seen in action in this plunk: http://plnkr.co/edit/PG0iHG?p=preview

like image 29
pkozlowski.opensource Avatar answered Nov 15 '22 08:11

pkozlowski.opensource