This is a common requirement, but it’s not immediately clear how to do it
in a straight-forward fashion. I’ve talked with Miško from the angular team
and he confirmed that the following is the propper way to dynamically add
directives:
app.directive('foo', function($compile, $parse) {
return {
restrict: 'A',
priority: 9999,
terminal: true, //Pause Compilation to give us the opportunity to add our
directives
compile: function(el, attr) {
attr.$set('ngModel', 'name')
var ngModelLink = $compile(el, null, 9999); //Resume compilation at
priority 9999 so that our directive doesn't get re-compiled
return function(scope) {
ngModelLink(scope); //Return the link function from the new compilation
}
}
}
});
The problem is that angular determines the list of directives to compile
*BEFORE* your directive is called. By the time you are executing your
compile function, it is too late and angular won’t compile any additional
directives you add to the current element (although it will compile
anything you add to children).
We cannot simply add the directive to element and call $compile() on it
either because then our directive will be compiled again, causing an
infinite loop.
What we have to do is stop compilation at our directive (by giving it a a
high priority and adding terminal: true. We can then add the attributes to
the element and call $compile() but pass it which priority to compile from.
If we pass the same priority as our directive it means our directive and
any higher-priority directives will not be compiled again (only directives
lower than the priority passed in will get compiled). This allows us to
essentially resume compilation allowing angular to scan for any new
directives and compile them.
There are a few other ways you can do this, but this one is the cleanest.
I’ve seen other people inject the directives themselves (e.g.
ngModelDirective) and then manually call the compile and link functions on
them, but this gets tricky when directives have additional require:sections and
is just not as clean.
--
You received this message because you are subscribed to the Google Groups
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.