查找已更改的数组中的项目

时间:2014-11-14 15:55:01

标签: angularjs

使用AngularJS我从AJAX请求中加载一系列项目,当我再次保存它们时,我只想回发已更改的项目而不是整个项目。但我没有看到一种简单的方法来获得已经改变的项目。在加载时,我尝试这样做:

originalData = angular.copy(data);
$scope.notifications = data;

那么当我保存时,我可以这样做:

var changed = $scope.notifications.filter(function (item, idx) {
    return !angular.equals(item, originalData[idx]);         // hopefully they stay 
                                                             // in the same order!?!
});

这似乎有效,但并不是非常强大。请注意有关订单的评论。我目前没有对这些项目进行重新排序,但我希望最终允许排序,我担心这会完全破坏这个并迫使我尝试通过{{1}查找originalData数组中的项目(这是每个项目具有的唯一属性),但这将是id。我错过了一些明显的东西吗?如果项目是脏的,我知道角度轨道并将类应用于绑定的DOM元素。我也知道您可以使用O(n^2),但我认为我需要在每个项目上设置每个属性的监视并设置某种类型每个项目的$watch标志,以便我可以在保存中过滤。

1 个答案:

答案 0 :(得分:1)

我决定这样做,我认为这比原始解决方案更好,因为它保留了每个项目的原始副本。当我加载数据时,我这样做:

angular.forEach(data, function(item) {
    item.$original = angular.copy(item);
}

这将制作项目的深层副本并将其存储在$original中。请注意,属性名称的$前缀很重要,因为当我去保存时,我这样做:

var changed = $scope.notifications.filter(function (item, idx) {
    return !item.$original || !angular.equals(item, item.$original);
});

angular.equals将忽略以$开头的所有属性(请参阅here):

  

在属性比较期间,将忽略函数类型的属性和名称以$开头的属性。

因此,它会对itemitem.$original进行深入比较,而不会尝试比较$original属性本身。 or的第一个子句负责处理新项目(显然不具有$original属性)。

现在,如果我稍后重新排序数组并不重要,因为我不是保留整个数组的副本,而是只保留每个项目的副本。