2

First, here's the issue reproduced in Plunker.

Basically I have a directive that will insert some element based on some info inside an ng-repeat. For my application, I'm using a pretty similar approach where it inserts an <img>, <video>, or <audio> element based on a mime type.

You'll see that when items are reordered in the array the ng-repeat is using, the item passed to the pageStyle directive isn't up to date with the new order anymore. It seems to retain whatever was in its spot before.

app.directive('pageStyle', function () {
  return {
    restrict: 'A',
    scope: {
      pageStyle: '='
    },
    replace: true,
    link: function (scope, element, attrs) {
      var ele;
      switch (scope.pageStyle) {
        case 'bold':
          ele = angular.element('<b>bold</b>');
          break;
        case 'italics':
          ele = angular.element('<i>italics</i>');
          break;
        case 'strike':
          ele = angular.element('<strike>strikethrough</strike>');
          break;
      }
      element.append(ele);
    }
  };
});

So I suppose my main question is how I get the directive to reevaluate when the order within an ng-repeat is changed.

John Slegers
  • 45,213
  • 22
  • 199
  • 169
specialkk
  • 25
  • 1
  • 6

1 Answers1

3

This is because of the use of 'track by'. 'track-by' causes not to re-build the dom elements completely, hence improves performance for ng-repeat rendering. http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm

Your problem requires re-rendering. So, remove 'track by'. You can check the issue by adding watch on pageStyle scope variable. That will give you clear insight of the issue.

gettingLearned
  • 126
  • 1
  • 8
  • Thanks, I was mistaken in how `track by` worked. I thought it was only necessary when I wanted to use `$index` within the markup, but it turns out it is injected anyway! – specialkk Sep 07 '15 at 17:36