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;
}
}