I showed how to inject any configuration constants into an AngularJS application using server-side templates in Inject valid constants into Angular blog post. In this blog post I will show how to allow users to configure your module, if they use it as a 3rd party dependency.
Take my confirm-click module as an example. It is a tiny single attribute directive that
shows a confirmation "Ok / Cancel" dialog before allowing ng-click or href event
to proceed. One can simply add this to the markup
1 | <button confirm-click="Submit this form?" ng-click="submit()">Submit</button> |
Under the hood, confirm-click directive replaces ng-click attribute with its
own utility function
1 | // confirm-click directive compile function |
By default we just use window.confirm method (line // 1) when asking the user before proceeding (line // 2).
Ordinary alert, prompt and confirm dialogs look ok, but they definitely do not match my website's visual style.
Instead we use a customized version of alertify.js library.
This library provides the same methods but made via actual modal dialogs; these can be customized using CSS.
We even have written a AngularJS wrapper kensho/ng-alertify that wraps
alertify.confirm and alertify.prompt into promise-returning methods.
1 | angular.module('MyApp', ['Alertify']) |
How can we make our confirm-click module use the Alertify.confirm or any other user-supplied function
instead of the default window.confirm?
Using AngularJS provider to pass config to the directive
We can set the desired ask function via a Provider instance.
Let us add a provider directly to the ConfirmClick module
1 | angular.module('confirm-click', []) |
We can inject ConfirmClickProvider anywhere, including the directive ConfirmClick (line // 1).
1 | angular.module('confirm-click', []) |
When we inject ConfirmClick into the directive, we get the result of the provider's ConfirmClick.$get()
method. In our case it will be the window.confirm by default.
Setting config via provider from the user module
Let us see how to change the ask function from our application code. Our application is the module
ClickApp that depends on confirm-click and Alertify modules.
1 | angular.module('ClickApp', ['confirm-click', 'Alertify']) |
Notice that we use the module.config method to inject an instance of the provider in line // 1
(only providers are allowed besides constants to be injected into the module's config callback).
The injected ConfirmClickProvider object has both set and $get method we have written,
thus we can pass our own ask function. In this case the custom function
needs to get an instance of Alertify. I found grabbing the injector instance
directly to get Alertify the simplest way.
The result looks nice even without any additional styling
