Ng-重复一次性绑定和“跟踪”更改

时间:2018-04-20 16:25:22

标签: angularjs angularjs-ng-repeat angular1.6 angularjs-track-by one-time-binding

我们的网络应用使用ngRepeat显示项目列表。数组及其对象永远不会更改,但内部对象的值可以由用户修改。

我们为每件商品生成一个独特的trackId。每次项目的值发生变化时,都会更新此trackId。

我们还使用一次性绑定语法来减少页面上观察者的数量(因为它可以快速攀升到数千人)。

然而,这种组合似乎并没有真正起作用;如果项目的trackId发生变化但对象的引用保持不变,则该项目重新呈现。

来自angularJS docs:

  

自定义表达式:可以使用任何AngularJS表达式   计算跟踪ID,例如使用函数或使用   收集物品的财产。项目跟踪项目。项目是一个   当项目具有唯一标识符时的典型模式,例如,数据库   ID。 在这种情况下,对象标识无关紧要。两个对象是   只要他们的id属性相同就被视为等效。跟踪   通过唯一标识符是最高效的方式,应该使用   只要有可能。

如果是这种情况,为什么在修改trackId时项目没有被销毁和重新创建?

例如:

$scope.friends = [
    {name:'John', age:25, id: 'John-25'},
    {name:'Mary', age:40, id: 'Mary-40'},
    {name:'Peter', age:85, id: 'Peter-85'}
];

$scope.change = function(i) {
    var f = $scope.friends[i];
    f.age = Math.floor(Math.random() * 100);
    f.id = f.name + '-' + f.age;
};

 <div ng-repeat="friend in friends track by friend.id">
    <div ng-bind="'Track id: ' + friend.id"></div>
    <div ng-bind="'Regular binding:' + friend.age"></div>
    <div ng-bind="::'One-time binding:' + friend.age"></div>
</div>

<button ng-click="change(0)">Change John's age</button>
<button ng-click="change(1)">Change Marys's age</button>
<button ng-click="change(2)">Change Peters's age</button>

在这个演示中,我希望在trackId发生变化时销毁该对象,并且应该使用新的一次性绑定值重新渲染该元素。

https://plnkr.co/edit/Lklq3ZNDUuggjgwmkoxj?p=preview

有没有人对如何解决这个问题有任何建议?出于性能原因,我们绝对无法删除一次性绑定。我还研究了angular-bind-notifier,但是这需要更新repeat中的每个绑定,因为它不能定位特定的行。

由于

2 个答案:

答案 0 :(得分:0)

保持每个id上的friend不变。

如果这个id真的只是每个朋友的ID,为什么需要更改?如果您使用该属性获取 more 而不是ID,可以考虑在对象上添加新属性并保持ID不变。

如果您不想这样做,您可以随时创建一些帮助函数,将当前朋友id-value存储在带有id键的字典中。然后,您可以通过friend.id更新或检索存储在该朋友ID中的值。

答案 1 :(得分:0)

ng-repeat在内部使用$watchCollection,这在数组上是一个浅表,因此更改数组项之一的属性不会导致ng-repeat更新。这里的文档有些误导。

您猜到您需要更改对象引用。切换ID后,将对象替换为浅表副本。这将导致$watchCollection检测到更改,然后ng-repeat将由于id更改而替换该项目。

$scope.friends = [
    {name:'John', age:25, id: 'John-25'},
    {name:'Mary', age:40, id: 'Mary-40'},
    {name:'Peter', age:85, id: 'Peter-85'}
];

$scope.change = function(i) {
    var f = $scope.friends[i];
    f.age = Math.floor(Math.random() * 100);
    f.id = f.name + '-' + f.age;

    $scope.friends[i] = Object.assign({}, $scope.friends[i]);
};

更新的插件: https://plnkr.co/edit/s2ztGQ?p=preview

相关问题