Javascript angularjs$watchCollection方法如何保存oldCollection引用?

Javascript angularjs$watchCollection方法如何保存oldCollection引用?,javascript,angularjs,lodash,Javascript,Angularjs,Lodash,我在屏幕上有一个“添加项目”按钮,当点击它时,它会将一个新项目添加到列表中 我使用$scope.$watchCollection监视一个函数,该函数返回所有可见项的列表 当我点击“添加项目”按钮时,我收到了无限摘要循环错误。 似乎$watchCollection克隆了列表,然后新集合不等于旧集合 JS-Bin演示: 您的问题是,每次摘要周期运行时,都会调用getVisibleItem。该函数清除可见项,然后通过.merge将所有内容添加回它。由于\uuu.merge生成项目的深度副本(从而使它

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

我使用
$scope.$watchCollection
监视一个函数,该函数返回所有可见项的列表

当我点击“添加项目”按钮时,我收到了无限摘要循环错误。 似乎$watchCollection克隆了列表,然后新集合不等于旧集合

JS-Bin演示:


您的问题是,每次摘要周期运行时,都会调用
getVisibleItem
。该函数清除可见项,然后通过
.merge
将所有内容添加回它。由于
\uuu.merge
生成项目的深度副本(从而使它们成为不同的引用),因此它会触发
$watchCollection
,这将包括另一个正在激发的摘要循环,从而导致摘要循环的无限循环

与其清除
\u visibleItems
然后将项目添加回其中,我建议您实际添加/删除其可见性已更改的项目(即,删除
\u visible items
中具有
isVisible=false
的项目,并添加只有
\u allItems
中具有
isVisible=true
的项目


或者,用简单的for循环或
[].push.apply(\u visibleItems,newVisibleItems)替换
.merge(\u visibleItems,newVisibleItems)
)将解决您的问题。

谢谢。现在我明白了。lodash合并是一个深度副本,可以创建新项目并将值复制到其中。
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;
        }

    }