paulroho
paulroho

Reputation: 1266

Why does $compile not evaluate the scope in directive created by ngRepeat

I have a directive creating instances of another directive using ngRepeat:

app.directive('prMain', function(){
  return {
    accept:'AE',
    template:'<div pr-item="" ng-repeat="item in items">{{item.name}}<div>'
  };
});

The sub directive is like this:

app.directive('prItem', function($compile){
  return {
    accept:'AE',
    template:'<p>{{item.name}}</p>',
    compile: function(elem) {
      elem.removeAttr('pr-item');
      return function(scope) {
        console.log(scope.item.color);
        var newEle = $compile('<div ng-style="{\'color\':\'red\'}">DIRECTIVE item.name</div>')(scope);
        elem.append(newEle);
      };
    },
  };
});

I would have expected two divs for each element in the array, the last one colored.

Instead, I get a confusing succession of text in the browser:

one

two
DIRECTIVE item.name

three
DIRECTIVE item.name
DIRECTIVE item.name

four
DIRECTIVE item.name
DIRECTIVE item.name
DIRECTIVE item.name

Please refer to this plunker.

The most important question is: why does ng-style not properly evaluate the scope expression? The second question is the reason for the output shown above.

Upvotes: 1

Views: 139

Answers (1)

floribon
floribon

Reputation: 19183

You are not using compile the right way. In particular, you are creating a closure of its elem parameter into the compilation method returned. Instead, each one of this function should work on its owm elem.

I'm not sure how to explain this, so here is some code and a fixed plunkr:

compile: function(elem_do_not_touch_elsewhere) {
  elem_do_not_touch_elsewhere.removeAttr('pr-item');

  return function(scope, elem_use_this_one) {
    var newEle = $compile('<div ng-style="{color:\'red\'}">DIRECTIVE item.name</div>')(scope);
    elem_use_this_one.append(newEle);
  };
},

http://plnkr.co/edit/aLyif5GxWySZs6RmZ6qm?p=preview

Upvotes: 2

Related Questions