Angular Directive Does Not Evaluate Inside ng-repeat

后端 未结 6 1696
予麋鹿
予麋鹿 2020-12-30 08:38

I have the following setup:

App/Directive

var app = angular.module(\"MyApp\", []);

app.directive(\"adminRosterItem\", function () {
    return {
            


        
相关标签:
6条回答
  • 2020-12-30 09:20

    I had the similar issue, where the ng-repeat in my view wass not evaluated if the view contained directive ('mydirective')

    My directive definition was

    angular.module('myApp')
      .directive('myDirective', function () {
        return {
          templateUrl: 'components/directives/mydirective.html',
          restrict: 'EA',
          controller: 'MyDirectiveController',
          controllerAs: 'vm',
          link: function (scope, element, attrs) {
          }
        };
      });
    

    and my view controller definition was

      angular.module('myApp')
        .component('myView', {
          templateUrl: 'app/views/myview.html',
          controller: myViewComponent,
          controllerAs: "vm"
        });
    

    you can notice both controllers are refered by 'vm' by using 'controllerAs' parameter. This is the reason for the problem. When the directive is present in the view, angular always refers the 'vm' defined in directive controller rather than view's.

    When I give different names for controller references, problem disappeared

    Now, My directive definition is

    angular.module('myApp')
      .directive('myDirective', function () {
        return {
          templateUrl: 'components/directives/mydirective.html',
          restrict: 'EA',
          controller: 'MyDirectiveController',
          controllerAs: 'directiveVM',
          link: function (scope, element, attrs) {
          }
        };
      });
    

    and my view controller definition was

      angular.module('myApp')
        .component('myView', {
          templateUrl: 'app/views/myview.html',
          controller: myViewComponent,
          controllerAs: "viewCtrlVM"
        });
    

    Hope it helps.

    0 讨论(0)
  • 2020-12-30 09:28

    i think the right way to approach this would be to send the object into admin roster item, like this:

    <tr ng-repeat="position in positions">
      <admin-roster-item pos="position">         
      </admin-roster-item>
    </tr>
    

    and in the directive:

    var app = angular.module("MyApp", []);
    
    app.directive("adminRosterItem", function () {
      return {
        restrict: "E",
        scope: {
            pos: "@"
        },
        template: "<td>{{ formattedText }}</td>", // should I have this?
        link: function(scope, element, attrs){
            // all of this can easily be done with a filter, but i understand you just want to     
            // know how it works
            scope.formattedText = scope.pos.Name + ' (' + scope.pos.Code + ')';
        }
      }
    });
    

    PS. i didn't test this!

    0 讨论(0)
  • 2020-12-30 09:31

    Ignoring all the theoretical aspects, you can get your code to work by making two simple changes.

    1. don't use mixed case in your attribute names. displaytext not displayText
    2. put the <td> tags outside the directive, in the template

    Do that and it will work; it think those are both Angular bugs.

    0 讨论(0)
  • 2020-12-30 09:35

    Agree that you need to think about where the directive begins and ends. Here's a plnkr that illustrates a directive bound to each item in the array - http://plnkr.co/edit/IU8fANreYP7NYrs4swTW?p=preview

    If you want the directive to encapsulate the enumerating of a collection defined by a parent scope it gets a bit tricker. I'm not sure if the following is 'best practice', but it's how i've handled it -- http://plnkr.co/edit/IU8fANreYP7NYrs4swTW?p=preview

    When relying on the directive to perform the iteration you get involved with transclusion, which is a made up word that means (as i understand it) take the content defined in the parent, push it into the directive and then evaluate it. I've been working with angular for a few months, and I'm starting to think that asking the directive to iterate is a smell, and I've always been able to design around it.

    0 讨论(0)
  • 2020-12-30 09:43

    Had exact same problem. Had a custom directive in an ng-repeat, table->tr->td->directive, and when sorting the table using ng-repeat and Array.sort the table did change order but the directives did not re-render. The problem was I was using

    track by $index
    

    removed the track by index from the ng-repeat and it was fixed.

    0 讨论(0)
  • 2020-12-30 09:45

    Instead of writing your directive as a child of ng-repeat, try keeping the custom directive on the same level as ng-repeat, this

    <tr ng-repeat="position in positions" admin-roster-item displayText="{{ position.Name + ' (' + position.Code + ')' }}"></tr>
    

    And furthermore, allow your custom directive to be used as an attribute. AngulaJS has defined ng-repeats priority as 1000, so at times when you custom directive is made, it does not go down well with ng-repeat.

    A second option (try only if the first one fails) is to set the priority of your custom directive more than that of ngRepeat i.e. to 1001.

    0 讨论(0)
提交回复
热议问题