Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs pass instance of each ng-repeat in HTML to directive

I'm thinking this should be simple but I'm missing something. How can I pass a flowObj in my ng-repeat below to my directive? I want to pass it to my directive then, on click, use that FlowObj, then apply some logic. I tried using the commented code in my directive

scope: { 
    test:"@" 
}

But it seems to screw up my CSS.

HTML:

<html>
   <head>
      <title></title>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   </head>
   <body>
      <div id="center_outer">
         <div id="center_inner" ng-controller="CtrlPageFlow">
            <div flowclick class="cflow" ng-repeat="flowObj in flows">
               {{flowObj.name}}
            </div>
         </div>
      </div>
   </body>
</html>

Here is my directive

angular.module('directives', ['opsimut']).directive('flowclick', function() {
    return {   
        /* 
        scope: {
            test:"@"   // set the attribute name on the directive's scope
        },
        */
        link: function(scope, elem, attr) {
            elem.bind('click', function(scope) {
                debugger;
                alert(scope.flowObj);
                //scope.name += '!';
                //scope.$apply();
            });
        }
    };
});

SOLUTION BASED ON ANSWER:

angular.module('directives', ['opsimut']).
directive('flowclick', function() {
  return {
    link: function(e, elem, attr) {
      // scope is the directive's scope,
      // elem is a jquery lite (or jquery full) object for the directive root element.
      // attr is a dictionary of attributes on the directive element.
      elem.bind('click', function(e1) {
        debugger;
        alert(e.flowObj);
      }, e);
    }
  };
});
like image 751
Mike6679 Avatar asked May 17 '13 22:05

Mike6679


1 Answers

SOLUTION: Remove the whole scope property from your directive and everything should work as expected.

ALSO: You'll need to rename the scope argument from this line:

elem.bind('click', function(scope) {

to something like:

elem.bind('click', function(e) {

because you are overwriting access to scope in your event handler by using the same name.

EXPLANATION:

The ng-repeat directive causes each of its clones to have their own new scope. Since directives on an element share scope by default, any other directives placed alongside the ng-repeat share its scope and have access to the current iteration's $scope variables. In other words, your custom directive already shares scope with ng-repeat and has access to flowObj by default.

The reason it didn't work when specifying a scope property on your custom directive is that this caused the directive to have its own isolate scope which did not share with ng-repeat and so you did not have access to variables on the clones' scopes.

like image 195
Dan Avatar answered Sep 21 '22 12:09

Dan