Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS:按ID合并对象,即在ID相同时替换旧条目_Javascript_Angularjs_Ionic - Fatal编程技术网

Javascript AngularJS:按ID合并对象,即在ID相同时替换旧条目

Javascript AngularJS:按ID合并对象,即在ID相同时替换旧条目,javascript,angularjs,ionic,Javascript,Angularjs,Ionic,我在AngularJS中使用Ionic,通过$http使用LocalFower数据库和AJAX。我的应用程序有一个包含以下数据的新闻流: { "feed":[ { "id":"3", "title":"Ein Hund", "comments:"1" }, { "id":"2", "title"

我在AngularJS中使用Ionic,通过$http使用LocalFower数据库和AJAX。我的应用程序有一个包含以下数据的新闻流:

{ 
    "feed":[  
        {  
             "id":"3",
             "title":"Ein Hund",
             "comments:"1"
         },
         {  
             "id":"2",
             "title":"Eine Katze",
             "comments":"2"
          }
       ],
   "ts":"20150907171943"
}
{  
   "feed":[  
      {  
         "id":"2",
         "title":"Eine Katze",
         "comments":"4"
      }
   ],
   "ts":"20150907171944"
}
ts
代表时间戳。我的应用程序通过LocalFower在本地保存提要

应用程序启动时,首先加载本地保存的项目:

$localForage.getItem("feed").then(function(val) { vm.feed = val; })
然后,它加载新的或更新的项目(
ts
),并合并新旧数据:

angular.extend(vm.feed, response.data.feed);
更新的项目如下所示:

{ 
    "feed":[  
        {  
             "id":"3",
             "title":"Ein Hund",
             "comments:"1"
         },
         {  
             "id":"2",
             "title":"Eine Katze",
             "comments":"2"
          }
       ],
   "ts":"20150907171943"
}
{  
   "feed":[  
      {  
         "id":"2",
         "title":"Eine Katze",
         "comments":"4"
      }
   ],
   "ts":"20150907171944"
}
也就是说,提要项2的注释计数已从2更改为4。当我合并新旧数据时,
vm.feed
有两个id=2的项

angularjs是否具有内置的“按id合并”功能,即。E从源复制到目标(如果是新元素),还是替换旧元素?如果angularjs没有这样的功能,那么实现它的最佳方法是什么

提前谢谢

角度合并(vm.feed,response.data.feed)

//编辑


它可能无法正确合并,因此您必须手动更新所有属性。更新
ts
属性,然后找到id为
id的对象并将其替换。

没有内置项,我通常编写自己的合并函数:

(function(){

  function itemsToArray(items) {
    var result = [];
    if (items) {
      // items can be a Map, so don't use angular.forEach here
      items.forEach(function(item) {
        result.push(item);
      });
    }
    return result;
  }

  function idOf(obj) {
    return obj.id;
  }

  function defaultMerge(newItem, oldItem) {
    return angular.merge(oldItem, newItem);
  }

  function mergeById(oldItems, newItems, idSelector, mergeItem) {
    if (mergeItem === undefined) mergeItem = defaultMerge;
    if (idSelector === undefined) idSelector = idOf;
    // Map retains insertion order
    var mapping = new Map();
    angular.forEach(oldItems, function(oldItem) {
      var key = idSelector(oldItem);
      mapping.set(key, oldItem);
    });
    angular.forEach(newItems, function(newItem) {
      var key = idSelector(newItem);
      if (mapping.has(key)) {
        var oldItem = mapping.get(key);
        mapping.set(key, mergeItem(newItem, oldItem));
      } else {
        // new items are simply added, will be at
        // the end of the result list, in order
        mapping.set(key, newItem);
      }
    });
    return itemsToArray(mapping);
  }


  var olds = [
    { id: 1, name: 'old1' },
    { id: 2, name: 'old2' }
  ];
  var news = [
    { id: 3, name: 'new3' },
    { id: 2, name: 'new2' }
  ];

  var merged = mergeById(olds, news);
  console.log(merged);
  /* Prints
  [
    { id: 1, name: 'old1' },
    { id: 2, name: 'new2' },
    { id: 3, name: 'new3' }
  ];
  */
})();

这将根据id从旧项构建
映射
,合并到新项中,并将映射转换回列表。幸运的是,根据规范,
Map
对象将按插入顺序对条目进行迭代。您可以提供您的
idSelector
mergeItem
功能。

谢谢hege_hegedus。根据您的代码,我编写了自己的代码,并尝试使用较少的循环来加快速度:

function updateCollection(localCollection, fetchedCollection)  {
    angular.forEach(fetchedCollection, function(item) {
        var append = true;
        for (var i = 0; i < localCollection.length; i++) {
            if (localCollection[i].id == item.id) {
                // Replace item
                localCollection[i] = item;
                append = false;
                break;
            } else if (localCollection[i].id > item.id) {
                // Add new element at the right position, if IDs are descending check for "< item.id" instead
                localCollection.splice(i, 0, item);
                append = false;
                break;
            }
        }

        if (append) {
            // Add new element with a higher ID at the end
            localCollection.push(item);
            // When IDs are descending use .unshift(item) instead
        }
    });
}
函数updateCollection(localCollection,fetchedCollection){
angular.forEach(fetchedCollection,函数(项){
var=true;
for(var i=0;iitem.id){
//在正确的位置添加新元素,如果id是递减的,则改为检查“

我认为,仍有改进的余地。E通过所有对象的迭代应该使用二进制搜索,因为所有项目都是按id排序的。

merge意味着您需要维护原始项目的某些属性,但从您的描述来看,我不确定是否是这样。用新项目完全替换旧项目更容易,但这将是手动的。对于返回的每个项,确定它是否已在集合中。如果是,请更换。如果否,则将其添加到末尾。