Cool, thanks both of you! Both approaches actually work as I intended.

@Daniel: wow, AWESOME reply! Thanks for bringing me to the next directive 
grokking level : )

Fwiw, I'll rename the resume func to something more verbose like 
resumeCompilation as it not only applies to the ngModel directive.

Cheers, 
Carsten

On Thursday, January 9, 2014 1:55:55 AM UTC+1, Daniel Tabuenca wrote:
>
> 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 angular+unsubscr...@googlegroups.com.
To post to this group, send email to angular@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to