如何
我有一个名为vm.queued_messages
的对象数组(我的控制器中vm
设置为this
),vm.queued_messages
中使用了ng-repeat
来显示div
的列表。
当我进行API调用以更改数据库中的基础模型时,我让API调用返回一个新的排队消息列表,并在我的控制器中将变量vm.queued_messages
设置为该新值,即新排队的消息列表。
vm.queued_messages = data; // data is the full list of new message objects
问题
这"完全替代" vm.queued_messages
完全按照我想要的方式工作。但我没有想到的事实是,即使是那个没有任何属性改变的列表中的对象也会离开,而新的对象正在取而代之。这与显示没有什么不同,因为新对象具有相同的键和值,它们在技术上是不同的对象,因此div
每次都秘密地离开和进入。这意味着有许多不受欢迎的.ng-enter
和.ng-leave
的发生,当我尝试将动画应用于这些div
时##引起了我的注意39;当他们进入或离开时。我希望单个div
可以在某次点击时执行.ng-leave
动画,但突然之间有一大堆动作了!
我的解决方案尝试
我创建了一个函数softRefreshObjectList
,它更新现有列表的键和值(以及任何全新的对象,或现在缺少的对象)以匹配新列表的那些,没有替换对象,AS保持他们的身份。我通过_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
和对象的值是对其他控制器变量的引用。在继续这个兔子洞之前,我想写这篇文章,以防我想到这个错误,或者我想念的东西。
我的问题
是否有更合适的方法来处理这种情况,这会使其更容易处理,还是完全绕过我的问题?
也许是一种向Angular发信号通知他们_id
而不是他们的引用来识别这些对象的方法,这样它就不会让它们离开并进入{{1没有改变。
或许是一个更好的_id
函数,它以不同的方式迭代对象,如果有关于我是如何做到这一点的蠢事。
答案 0 :(得分:0)
感谢Petr的评论,我现在知道track by
的{{1}}。您可以在元素中指定一个“标识”该元素的字段,以便角度可以知道该元素何时真正离开或进入。就我而言,该字段为_id,将ng-repeat
添加到我的track by message._id
(ng-repeat
)可以完美地解决我的问题。
文档here。搜索ng-repeat="message in ctrl.queued_messages track by message._id"
。