繁体   English   中英

NG重复一次绑定和“跟踪”更改

[英]Ng-repeat one-time binding and “track by” change

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

我们为每个项目生成唯一的trackId。 每当项目的值更改时,此trackId都会更新。

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

但是,这种组合似乎并没有真正起作用。 如果项目的trackId发生更改,但对象的引用保持不变,则不会重新渲染该项目。

从angularJS文档中:

自定义表达式:可以使用任何AngularJS表达式来计算跟踪ID,例如使用函数或使用收集项目上的属性。 当项目具有唯一标识符(例如数据库ID)时,按item.id跟踪的项目中的item是一种典型模式。 在这种情况下,对象身份无关紧要。 只要两个对象的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,但是这将要求更新重复中的每个绑定,因为它不能针对特定的行。

谢谢

保持每个friendid不变。

如果此id确实只是每个朋友的ID,为什么需要更改? 如果您正在使用该属性的东西比一个ID ,也许考虑对象上添加新的属性,并保持ID的常数。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM