简体   繁体   English

angularjs $ watchCollection方法如何保留oldCollection参考?

[英]How angularjs $watchCollection method keep the oldCollection reference?

I have an 'Add Item' button on the screen which adds a new item to a list when it's clicked. 我在屏幕上有一个“添加项目”按钮,单击该按钮会将新项目添加到列表中。

I use $scope.$watchCollection to watch a function which returns a list of all visible items. 我使用$scope.$watchCollection来观看一个返回所有可见项列表的函数。

When I clicked the 'add item' button, I received unlimited digest loop error. 当我点击“添加项目”按钮时,我收到了无限的摘要循环错误。 It seems that $watchCollection clones the list, and then the newCollection is alwasy not equle the oldCollection. 似乎$ watchCollection会克隆该列表,然后newCollection并不等于oldCollection。

JS Bin Demo: https://jsbin.com/mavolecipu/1/edit?html,js,output 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;
        }

    }

Your issue is that every time a digest cycle runs, getVisibleItem is called. 您的问题是,每次摘要循环运行时,都会调用getVisibleItem That function clears _visibleItems and then adds everything back to it via _.merge . 该函数清除_visibleItems ,然后通过_.merge将所有内容添加回去。 Because _.merge makes deep copies of the items (thus causing them to be different references), it triggers $watchCollection , which will include another digest cycle being fired, causing an infinite loop of digest cycles. 由于_.merge制作项目的深层副本(因此使它们成为不同的引用),因此它将触发$watchCollection ,其中将包括另一个被触发的摘要循环,从而导致摘要循环无限循环。

Rather than clearing _visibleItems and then adding items back into it, I recommend you do the work of actually adding/removing items that have had their visibility changed (ie remove items in _visibleItems that have isVisible=false and add in items that are only in _allItems with isVisible=true . 我建议您做一些工作,而不是先清除_visibleItems然后再向其中添加项目,而是实际添加/删除其可见性已更改的项目(即,删除_visibleItems中具有isVisible=false项目,并添加仅在_allItems中的项目使用isVisible=true

Alternately, replacing _.merge(_visibleItems, newVisibleItems) with a simple for-loop or [].push.apply(_visibleItems, newVisibleItems will resolve your issue. 或者,将_.merge(_visibleItems, newVisibleItems)替换为简单的for循环或[].push.apply(_visibleItems, newVisibleItems将解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM