I’m using jQuery dialogs in an AngularJS application. I’ve struggled to find
a way to use them that follows angular ‘best practices’. My first attempt used a
directive for the DOM manipulation and a controller for binding to the scope. I was
uncomfortable with this approach because I was splitting the code between two
different artifacts. I also ended up adding the open dialog method to the $rootScope
which is the same as making it global.
The other method I tried was using a single controller. This was also not best
practice since I was manipulating DOM in a controller. I still had to put the
open method on $rootScope.
Others have suggested using a service, but I would be accessing the DOM in the
service and what would I do about scope?
Then I thought, what if I created a generic directive that would allow me to
set the dialog options in the markup? Furthermore, what if I could register the
the dialog in a service so I could inject it into a controller and open the dialog
using that controller? It turns out it’s possible with a little angular black magic.
Meet the jqdialog directive.
Step one: create directive that provides the jQuery dialog options as scope variables. I capture
the options directly off the $.ui.dialog and then add them to the scope using ‘&’ bindings. This
allows any values to be entered without having to convert from strings with the downside of having to
place strings in quotes inside the attribute. Then in the link function, I can loop thru the options,
and if they have values on the scope, I put them in the options array which is passed to the dialog
function.
Step two: require a dialogName attribute and use that to create a service for the dialog with
open and close methods. We’ll need to create the service in the compile function so it will
be available when dependencies are injected. Then we’ll add the methods in the link function
when the scope is available. Finally, we must call the transclude method using the $parent scope
instead of ng-transclude so we get the correct scope for contents in the dialog.
The full version is available on
github. Here is an example
of the tag usage.
1234567891011
<divng-app="app"ng-controller="DemoCtrl"><buttonng-click="testDialog();">Open Dialog</button><jqdialogdialog-name="Test"title="'Test Dialog'"auto-open="false"width="400"height="300"on-open="onOpen"buttons="{'OK': onOk, 'Cancel': onCancel}"ng-controller="DialogCtrl"><h3>This is a test dialog</h3><labelfor="fullName">Full Name:</label><inputid="fullName"ng-model="fullName"/></jqdialog></div>