我有一个简单的ngRepeat,如下所示:
<some-element ng-repeat="singleRecord in arrayOfRecords track by singleRecord.id">
<!-- stuff -->
</some-element>
arrayOfRecords
已从服务器更新,可能包含新数据。
ngRepeat
track by
功能可以确定何时将新元素添加到数组并自动更新DOM而不更改现有元素。我希望在有新数据进入或删除旧数据时挂钩该代码并执行回调函数。是否可以通过Angular轻松完成此任务?
根据我的理解,$$watchers
会在某些变量发生变化时触发回调,但我不知道如何进行黑客攻击。这是正确的方向吗?
注意:我知道我可以手动保存arrayOfRecords
并在我获取它们时将其与新值进行比较以查看更改的内容。但是,由于Angular已经提供了具有此逻辑的track by
功能,如果我可以让Angular在从数组中添加或删除元素时自动触发事件回调,那将是很好的。复制已存在于Angular中的逻辑是没有意义的。
答案 0 :(得分:3)
可能你可以创建一个指令并将其与ng-repeat一起添加,因此创建指令(当项目由ng-repeat添加时)将发出一个事件,类似地,当项目被销毁时,它将发出另一个事件。
这里有一个简单的实现:
.directive('tracker', function(){
return{
restrict:'A',
link:function(scope, el, attr){
scope.$emit('ITEM_ADDED', scope.$eval(attr.tracker))
scope.$on('$destroy', function(){
scope.$emit('ITEM_REMOVED', scope.$eval(attr.tracker))
});
}
}
});
并将其用作:
<some-element
ng-repeat="singleRecord in arrayOfRecords track by singleRecord.id"
tracker="item">
并在父控制器上监听这些事件。
<强> Demo 强>
或者以不同的方式使用函数绑定,而不使用隔离范围。
.directive('tracker', function() {
return {
restrict: 'A',
link: function(scope, el, attr) {
var setter = scope.$eval(attr.tracker);
if(!angular.isFunction(setter)) return;
setter({status:'ADDED', item:scope.$eval(attr.trackerItem)});
scope.$on('$destroy', function() {
setter({status:'REMOVED', item:scope.$eval(attr.trackerItem)});
})
}
}
});
<强> Demo 强>
上面的一个特定于您的问题,因为没有其他内置方式,请注意,如果您要真正找到添加/删除的项目,您也可以通过区分2个列表在控制器中执行此操作。您可以尝试使用像_.unique
这样的lodash api甚至是简单的循环比较来查找结果。
function findDif(oldList,newList){
return {added:_.uniq(newList, oldList), removed:_.uniq(oldList, newList)};
}
<强> Demo 强>
答案 1 :(得分:0)
您可以将其更改为:
<div ng-model="arrayOfRecords">
<some-element ng-repeat="singleRecord in arrayOfRecords track by singleRecord.id">
<!-- stuff -->
</some-element>
</div>
一旦arrayOfRecords更改,模型将更改。