更新,而不是替换,用于ng-repeat的列表

时间:2016-06-15 14:33:25

标签: javascript angularjs angularjs-ng-repeat

如何

我有一个名为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函数,它以不同的方式迭代对象,如果有关于我是如何做到这一点的蠢事。

1 个答案:

答案 0 :(得分:0)

感谢Petr的评论,我现在知道track by的{​​{1}}。您可以在元素中指定一个“标识”该元素的字段,以便角度可以知道该元素何时真正离开或进入。就我而言,该字段为_id,将ng-repeat添加到我的track by message._idng-repeat)可以完美地解决我的问题。

文档here。搜索ng-repeat="message in ctrl.queued_messages track by message._id"