$ index的ng-repeat轨迹打破了图像字段排序

时间:2015-08-13 17:43:40

标签: javascript angularjs

我有一个带有少量列的ng-repeat表。 te列之一是图像字段。这是一个带有图像列的片段和其他一个片段:

    <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>

按照目前的情况,当我点击按列排序时,所有列都按其关联的行排序,之外的图像行;它停留在同一个地方。

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

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

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

编辑(解决方案): 我最终删除了接受答案中建议的一次性绑定,并修复了问题。但是,经过一番考虑之后,我们认为我们宁愿获得一次性延迟加载而不是track by性能,因为列表会很小。

对于有这个问题的任何其他人来说,在这种情况下,与$ index结合使用跟踪图像的时间似乎是问题。

2 个答案:

答案 0 :(得分:2)

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

根据AngularJS Doc:

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

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

答案 1 :(得分:1)

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

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

从绑定到指令输入中删除::应允许指令按预期运行,即使没有完全重新呈现也是如此。通常,::仅适用于表达式在渲染后是永久性的情况;在这种情况下,由于订单过滤器,它们不是永久性的。