Hm, next stumbling block: the static 'name' value from above. I'd like to get that value from an expression, evaluated against the scope of the element.
Which forces me to put the attr.$set call into the link function. That, again, will cause ngModel to not pick up the binding. Again, the rendered dom will have eg. <input foo ng-model="formData.email"> correctly, but will not bind to formData.email. Here's a jsbin: http://jsbin.com/OyaCigE/5/edit?html,js,output Further ideas? On Thursday, January 9, 2014 12:49:13 PM UTC+1, Carsten Kraus wrote: > > 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.