2

I'm trying to write a directive that dynamically adds directives of another type to the DOM and compile them. It seems to work when using a string template, but fails when using templateUrl. Here's a jsfiddle of the working template string:

app.directive('clicker', function($compile) {
    'use strict';

    return {
        compile: function(tElement, tAttrs) {
            var t = '<div data-pop>Pop</div>';

            return function(scope, iElement) {
                iElement.click(function() {
                    $('body').append($compile(t)(scope));
                });
            };
        }
    }
});

app.directive('pop', function() {
    'use strict';

    return {
        template: '<div>Testing template</div>'
        //templateUrl: 'partials/pop.html'
    };
});

http://jsfiddle.net/89AYX/

But if swapped to templateUrl (with an html file containing exactly what's in the template string) it will only work once. It does add an element to the DOM but it does not contain the templateUrl contents nor does it call the linking function in the dynamically added directive ...

Trying to add two of them will make the DOM look something like:

<div data-pop><!-- content of pop.html --></div>
<div data-pop></div>
<div data-pop></div>
10
  • Seems like a bug, honestly. Although, I can't really think of a good reason to do what you're trying to do. What are you trying to accomplish that you couldn't accomplish with ng-repeat? Commented Nov 19, 2012 at 19:17
  • I have a list of users, which I'm rendering out with ng-repeat, but I would like to register an onclick handler to dynamically create a modal which is a directive I've created (with a templateUrl ideally). This way the modal inherits the user's scope from ng-repeat. Commented Nov 20, 2012 at 17:09
  • Why not just register a single instance of your modal directive on the page, and then have the ng-click in the repeated items alter the scope to show the modal? Why does the modal directive need to be added dynamically? Commented Nov 20, 2012 at 18:10
  • Would like to be able to stack multiple modals ... clicking on a user might open the Edit User modal, but then clicking on something with that might open an additional modal. Commented Nov 20, 2012 at 18:18
  • Why not have a directive, that creates an array of items that ng-repeat's your modal? Commented Nov 20, 2012 at 18:22

1 Answer 1

2

Adding scope.$apply() worked for me. Tested with jQuery 1.9.0 and Angular 1.0.3.

iElement.bind('click', function() {
    $('body').append($compile(t)(scope));
    scope.$apply();  // cause a $digest cycle to run, since we're "outside" Angular
});

This fiddle uses an inlined template, but I also tested with a local webserver that had to do a separate HTTP GET to get the partial.

Sign up to request clarification or add additional context in comments.

2 Comments

And the $apply is just a consequence of it being a dom callback. It could be done this way instead.
Hi, would you please provide ideas on my new proposed API to make programmatically adding directives a simpler process? github.com/angular/angular.js/issues/6950 Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.