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