【问题标题】:How angularjs $watchCollection method keep the oldCollection reference?angularjs $watchCollection 方法如何保留 oldCollection 参考?
【发布时间】:2018-04-11 15:11:19
【问题描述】:

我在屏幕上有一个“添加项目”按钮,当它被点击时,它会将一个新项目添加到列表中。

我使用$scope.$watchCollection 观察返回所有可见项目列表的函数。

当我单击“添加项目”按钮时,我收到了无限摘要循环错误。 似乎 $watchCollection 克隆了列表,然后 newCollection 总是不等于 oldCollection。

JS Bin 演示: https://jsbin.com/mavolecipu/1/edit?html,js,output

function MainController($scope) {
        var ctrl = this;
        var _index = 1;
        var _visibleItems = [];
        var _allItems = [];



        ctrl.addItem = addItem;
        ctrl.visibleItems = [];


        $scope.$watchCollection(getVisibleItem, function (newVal, oldVal) {
          // it looks like the newVal is always not equal oldVal?? 
          if(newVal!== oldVal){
               ctrl.visibleItems = newVal;
           }

        });


        function addItem() {

            _allItems.push({
                index: _index,
                isVisible: true
            });


            _index = _index+1;

        }


        function getVisibleItem() {
            var newVisibleItems = _(_allItems).filter({isVisible: true}).value();

            // use same reference
            _visibleItems.length = 0;

            _.merge(_visibleItems, newVisibleItems);

            return _visibleItems;
        }

    }

【问题讨论】:

    标签: javascript angularjs lodash


    【解决方案1】:

    您的问题是每次运行摘要循环时,都会调用 getVisibleItem。该函数清除_visibleItems,然后通过_.merge 将所有内容添加回它。因为_.merge 对项目进行了深层复制(从而导致它们成为不同的引用),所以它会触发$watchCollection,这将包括另一个被触发的摘要循环,从而导致摘要循环的无限循环。

    与其清除 _visibleItems 然后将项目重新添加到其中,我建议您实际添加/删除已更改其可见性的项目(即删除 _visibleItems 中具有 isVisible=false 的项目并添加在仅在 _allItemsisVisible=true 中的项目中。

    或者,将 _.merge(_visibleItems, newVisibleItems) 替换为简单的 for 循环或 [].push.apply(_visibleItems, newVisibleItems 将解决您的问题。

    【讨论】:

    • 谢谢。现在我明白了。 lodash 合并是一个深拷贝,它总是创建新项目并将值复制到其中。
    猜你喜欢
    • 2017-06-02
    • 2018-12-14
    • 2015-03-04
    • 2021-05-30
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多