AngularJS:自定义迭代/数据转换和分组…当简单的ng-repeat只是won'

AngularJS : custom iterations/data transformations and grouping... when simple ng-repeat just won't cut it

本文关键字:ng-repeat 简单 只是 won 迭代 自定义 数据 转换 AngularJS      更新时间:2023-09-26

仍然这个问题Angular.js更复杂的条件循环,但我觉得问题的答案是正确的,所以我接受了它。

让我比原来的问题更详细地阐述一下。

I'm try to get this

<h3>11.4.2013</h3>
<ul>
 <li>oofrab | 4 | 11.4.2013 14:55 <button>remove</button></li>
 <li>raboof | 3 | 11.4.2013 13:35 <button>remove</button></li>
</ul>
<h3>10.4.2013</h3>
<ul>
 <li>barfoo | 2 | 10.4.2013 18:10 <button>remove</button></li>
 <li>foobar | 1 | 10.4.2013 12:55 <button>remove</button></li> 
</ul>

从这个数据结构

[
    {
        "id": 4,
        "name": "oofrab",
        "date": "2013-11-04 14:55:00"
    },
    {
        "id": 3,
        "name": "raboof",
        "date": "2013-11-04 13:55:00"
    },
    {
        "id": 2,
        "name": "barfoo",
        "date": "2013-10-04 18:10:00"
    },
    {
        "id": 1,
        "name": "foobar",
        "date": "2013-10-04 12:55:00"
    }
]

基本上,在标准ng-repeat之上,我想添加的唯一额外的东西就是那些标题。我简直不敢相信我必须通过添加它们来解决这么多问题。

这是我最终使用我在第一个问题中得到的答案http://plnkr.co/edit/Zl5EcsiXXV92d3VH9Hqk?p=preview

请注意,实际上最多可以有400个条目。我需要能够添加/删除/编辑条目在飞行

关于plunker的例子是这样的:

遍历原始数据,创建如下所示的新数据结构

{
  "2013-10-05": [
    {
      "id": 4,
      "name": "oofrab",
      "date": "2013-10-05 14:55:00",
      "_orig_index": 0
    },
    {
      "id": 3,
      "name": "raboof",
      "date": "2013-10-05 13:55:00",
      "_orig_index": 1
    }
  ],
  "2013-10-04": [
    {
      "id": 2,
      "name": "barfoo",
      "date": "2013-10-04 18:10:00",
      "_orig_index": 2
    },
    {
      "id": 1,
      "name": "foobar",
      "date": "2013-10-04 12:55:00",
      "_orig_index": 3
    }
  ]
}

允许我通过执行

得到我想要的结果
<div ng-repeat="(date,subItems) in itemDateMap">
<h3>{{date}}</h3>
<ul>
  <li ng-repeat="item in subItems">
    {{item.name}} | {{item.id}} | {{item.date}}
    <button type="button" ng-click="removeItem(item._orig_index)">x</button>
  </li>
</ul>  
</div>

好了。但随之而来的是一大堆问题。每次增加一个新项目,我都必须重新构建itemDateMap,每次删除一个项目,我都必须重新构建itemDateMap,每次更改日期,我都必须重新构建itemDateMap。当我想要删除一个项时,我必须首先获得其原始引用的索引。每次itemDateMap被重建,整个东西都被重新渲染。而且它不能排序,因为它是一个对象而不是数组。

当有几百个条目时,它也会变得非常非常慢。我在某个地方读到ng-repeat非常聪明,可以观察值,移动节点而不是重新渲染所有东西,但当我重建整个结构时,它肯定不会以这种方式工作。

这不可能,所有这些麻烦都是为了做一件非常非常简单的事情。

我该怎么办?

这是我的建议-只使用一个结构,并且只向作用域(映射)公开一个结构。并创建一个函数,将项目数组添加到映射中,并创建一个函数,将映射转换为数组(我假设您需要此数组用于服务器通信或其他用途)。

  var toKey=function(item){
    return moment(item.date).format("YYYY-MM-DD");
  }
  $scope.itemDateMap = {};
  $scope.addItemToDateMap=function(item){
    var key = toKey(item);
    if(!$scope.itemDateMap[key]){
      $scope.itemDateMap[key] = [];
    }
    $scope.itemDateMap[key].push(item);    
  }
  $scope.removeItemFromDateMap=function(item){
    var key = toKey(item), subitems = $scope.itemDateMap[key];
    var index = subitems.indexOf(item);
    subitems.splice(index,1);
    if(subitems.length === 0){
      delete $scope.itemDateMap[key];
    }
  }
  var addArrayToMap = function(items){
    for(var i=0; i<items.length; i++){
      var item = items[i]; 
      $scope.addItemToDateMap(item);
    }
  };
  $scope.mapToArray = function(){
    var items = [];
    for(var key in $scope.itemDateMap){
      var subitems = $scope.itemDateMap[key];
      for(var j=0;j<subitems.length;j++){
        var item = subitems[j];
        items.push(item);
      }
    }
    return items;
  }
我已经用我的建议更新了你的plkkr。我认为它的性能相当好。

哦-我刚刚注意到你想要排序-我没有时间更新我的例子,但它不是很复杂。使用这个结构来代替(数组和对象和数组,而不是对象和数组)——这样你就可以在根数组上使用orderBy:'date':

[
{
  date:"2013-10-05",
  items: [
    {
      "id": 4,
      "name": "oofrab",
      "date": "2013-10-05 14:55:00"
    },
    {
      "id": 3,
      "name": "raboof",
      "date": "2013-10-05 13:55:00"
    }
  ]
},
{
date:"2013-10-04",
items: [
    {
      "id": 2,
      "name": "barfoo",
      "date": "2013-10-04 18:10:00"
    },
    {
      "id": 1,
      "name": "foobar",
      "date": "2013-10-04 12:55:00"
    }
  ]
}
]