怎么样
我有一个名为 vm.queued_messages
的对象数组(vm
在我的 Controller 中设置为 this
),以及 vm .queued_messages
在 ng-repeat
中用于显示 div
的列表。
当我进行更改数据库中的底层模型的 API 调用时,我让 API 调用返回一个新的排队消息列表,并且在我的 Controller 中我将变量 vm.queued_messages
设置为那个新值,那个新的排队消息列表。
vm.queued_messages = data; // data is the full list of new message objects
问题
vm.queued_messages
的“完全替换”一开始完全符合我的要求。但我没有想到的是,即使是该列表中没有任何属性更改的对象也在离开,新对象正在取而代之。这对显示没有影响,因为新对象具有相同的键和值,它们在技术上是不同的对象,因此 div
每次都 secret 地离开和进入。这意味着有许多不需要的 .ng-enter
和 .ng-leave
正在发生,当我试图对这些 应用动画时引起了我的注意code>div
在他们进入或离开时。我希望单个 div
可以在点击时执行 .ng-leave
动画,但突然间有很多这样了!
我的解决方案尝试
我创建了一个函数softRefreshObjectList
,它更新现有列表的键和值(以及任何全新的对象,或现在不存在的对象)以匹配新列表的键和值,而无需替换对象,至于保持其身份。我通过它们的 _id
字段在新列表和旧列表之间匹配对象。
softRefreshObjectList: function(oldObjs, newObjs) {
var resultingObjList = [];
var oldObjsIdMap = {};
_.each(oldObjs, function(obj) {
oldObjsIdMap[obj._id] = obj;
});
_.each(newObjs, function(newObj) {
var correspondingOldObj = oldObjsIdMap[newObj._id];
if (correspondingOldObj) {
// clear out the old obj and put in the keys/values from the new obj
for (var key in correspondingOldObj) delete correspondingOldObj[key];
for (var key in newObj) correspondingOldObj[key] = newObj[key];
resultingObjList.push(correspondingOldObj);
} else {
resultingObjList.push(newObj);
};
});
return resultingObjList;
}
它适用于某些事情,但对于其他 ng-repeat
列表我会得到奇怪的行为,我相信是因为 delete
和对象的值被引用到其他 Controller 变量。在继续探索这个兔子洞之前,我想发表这篇文章,以防万一我想错了,或者我遗漏了什么。
我的问题
是否有更合适的方法来处理这种情况,使其更容易处理,或者完全绕过我的问题?
也许是一种向 Angular 发出信号的方法,表明这些对象是由它们的
_id
而不是它们的引用来标识的,这样就不会让它们离开和进入只要_id
不变。或者也许是更好的
softRefreshObjectList
函数,它以不同的方式遍历对象,如果我的操作方式有问题的话。
最佳答案
感谢 Petr 的评论,我现在知道了 ng-repeat
的 track by
。在这里您可以在元素中指定一个“标识”该元素的字段,以便 Angular 可以知道该元素何时真正离开或进入。在我的例子中,该字段是 _id,并将 track by message._id
添加到我的 ng-repeat
(ng-repeat="message in ctrl.queued_messages track通过 message._id"
) 完美解决了我的问题。
文档 here .搜索跟踪方式
。
关于javascript - 更新而不是替换用于 ng-repeat 的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37838424/