2

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

因此,让我比我在原始问题中所做的详细说明。

我试图得到这个

<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 非常聪明,可以观察值,在 dom 中移动点头,而不是重新渲染所有内容,但是当我重建整个结构时,它肯定不会以这种方式工作。

这不可能是对的,做一件非常非常简单的事情会很麻烦..

我该怎么办?

4

1 回答 1

3

这是我的建议 - 只使用一种结构,并且只将一种结构暴露给范围(地图)。并创建一个函数来向地图添加一个项目数组,以及一个将地图转换为数组的函数(我假设您需要这个数组来进行服务器通信或其他东西)。

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

我已经用我的建议更新了你的 plnkr。我认为它的表现相当不错。

哦 - 我刚刚注意到你想要它排序 - 我没有时间更新我的示例,但它不是很复杂。改为使用此结构(带有数组的对象的数组,而不是带有数组的对象) - 这样您就可以在根数组上使用 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"
    }
  ]
}
]
于 2013-04-12T09:50:53.303 回答