n -repeat track by $index打破图像字段排序

ng-repeat track by $index breaks image field sorting

本文关键字:图像 字段 排序 index -repeat track by      更新时间:2023-09-26

我有一个包含少量列的ng-repeat表。其中一列是图像字段。下面是图像列和其他列之一的代码片段:

    <tbody>
        <tr ng-repeat="insight in insights | orderBy:sort track by $index">
            <td>
                <select ng-model="insight.type" ng-change="setType(insight)" required="required">
                    <option value="INSIGHT">Insight</option>
                    <option value="EVIDENCE">Evidence</option>
                </select>
            </td>
<!--Image thing-->
            <td>
                <a ng-href="{{:: insight.imgurl}}" target="_blank"><img class="full" wb-lazy-load-image="{{:: insight.imgurl}}" data-height="600" data-width="800"></a>
            </td>
        ...
    </tbody>

事实上,当我点击按列排序时,所有的列都与它们相关联的行排序,除了用于图像行;它停留在同一个位置。

如果我在<tr>处删除track by $index代码,它会按预期重新排序所有列。

知道为什么或者我能做些什么来解决这个问题吗?

编辑:

FWIW - sort在我的控制器中定义为:$scope.sort = ['-primary', '-live'];

编辑(解决方案):我最终删除了一次绑定建议在接受的答案,它解决了这个问题。然而,经过一番考虑,我们决定我们宁愿获得一次性惰性加载的性能收益,而不是track by的性能,因为列表会很小。

对于其他有此问题的人来说,在这种情况下,一次性绑定图像与track by $index似乎是问题。

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="orderByExample">
  <script>
  angular.module('orderByExample', [])
    .controller('ExampleController', ['$scope', function($scope) {
      $scope.friends =
          [{name:'John', phone:'555-1212', age:10,sort:['-age','-name']},
           {name:'Mary', phone:'555-9876', age:19,sort:['-age','-name']},
           {name:'Mike', phone:'555-4321', age:21,sort:['-age','-name']},
           {name:'Adam', phone:'555-5678', age:35,sort:['-age','-name']},
           {name:'Julie', phone:'555-8765', age:29,sort:['-age','-name']}];
    }]);
</script>
<div ng-controller="ExampleController">
  <table class="friend">
    <tr>
      <th>Name</th>
      <th>Phone Number</th>
      <th>Age</th>
    </tr>
    <tr ng-repeat="friend in friends | orderBy:sort track by $index">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
    </tr>
  </table>
</div>
</body>

根据AngularJS文档:

  • 注意:track by必须总是最后一个表达式:
  • https://docs.angularjs.org/api/ng/directive/ngRepeat

一个可能对你有帮助的例子:

<div ng-repeat="model in collection | orderBy: 'id' as filtered_result track by model.id">
    {{model.name}}
</div>

似乎一次性绑定语法是罪魁祸首。使用{{::insight.imgurl}}将创建一个一次性绑定,其中将从该元素中删除监视程序。然而,当与wb-lazy-load-image结合使用时,似乎该指令认为它正在获得双向绑定,但实际上是获得单向绑定。

我最好的猜测没有看到这个指令是如何工作的,该指令采取insight.imgurl并执行网络调用来查找图像。然后,过滤器导致数组改变顺序,但由于单向绑定,指令不知道顺序已经改变。因此,该指令在不正确的位置加载图像。删除track by $index将导致ng-repeat$digest循环中被不同地处理,导致问题指令被完全重新渲染。

从指令输入的绑定中删除::应该允许指令按预期运行,即使没有完全重新渲染。一般来说,::仅用于表达式在呈现后将是永久性的情况;在本例中,由于使用了订单过滤器,它们不是永久性的。