binding ng directives inside custom directive

I have the following code with custom directive 'my-repeater':

<div ng-controller="AngularCtrl">
  <div my-repeater='{{items}}'>Click here</div>
</div>​

Here is my custom directive:

myApp.directive('myRepeater', function($compile) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        var myTemplate = "<div ng-click='updateRating({{item}});' ng-class='getRatingClass({{rating}});'>{{rating}}</div>";
            var items = scope.items;
            console.log('length: ' + items.length);
            for (var i = 0; i < items.length; i++) {
                var child = scope.$new(true);
                console.log(items[i].ratings);
                child.item = items[i];
                child.rating = items[i].ratings;                    
                var text = $compile(myTemplate)(child);
                element.append(text);
            }
   }
};

});

ng-click and ng-class bindings are not happening properly inside my custom directive. Can anyone help me with what i am doing wrong here?

Here is the JS Fiddle. http://jsfiddle.net/JSWorld/4Yrth/5/

Hi I've updated your sample to what I think you want to do.

http://jsfiddle.net/46Get/2/

  • First, in directives like ng-click='updateRating({{item}});' that receive an expression you dont need to use '{{}}' because it is already executed in the scope.

  • Second, when you need to add siblings to your directive, you need to do it in the compilation phase and not the linking phase or just use ng-repeat for that matter

I added .ng-scope { border: 1px solid red; margin: 2px} to @rseidi's answer/fiddle, and I discovered that a scope is being created by the $compile service for each item in the template -- i.e., each <div>. Since you have so many items to display, I assume that fewer scopes will be much better. After trying a bunch of different things, I discovered that Angular seems to create a new scope for each "top level" element. So a solution is to create an outer div -- i.e., ensure there is only one "top level" element:

var mainTpl = '<div>';  // add this line
...
for(...) { }
mainTpl += '</div>';    // add this line

Fiddle

Now, only the outer div creates a scope, since there is only one "top level" element now, instead of one per item.