AngularJS:自定义迭代/数据转换和分组…当简单的ng-repeat只是won'
AngularJS : custom iterations/data transformations and grouping... when simple ng-repeat just won't cut it
仍然这个问题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"
}
]
}
]
- ng init中的表达式无法使用ng repeat
- Angular ng repeat order将多个字段作为一个字段
- 访问ng repeat中的第一个项目
- Angular js+ng repeat+字母数字索引不起作用
- 如何正确应用Angularjs ng repeat
- AngularJS Navigation (li ng-repeat, create header li), DOM
- 如何使用ng repeat中的选定输入更新我的对象
- 无法使用ng repeat检索动态创建的JSON对象的属性
- 使用 ng-repeat访问 ng 表单元素/值
- Toggle Switch在包含ng model和ng repeat之后不进行切换
- 如何在ng repeat angular js中使用$index
- 在Angularjs中,我如何使用ng repeat、ng model和ng click来动态更改内容
- ng repeat在ng repeat-过滤器不工作
- 在ng repeat中使用带有orderBy的方法
- 简单的ng-Repeat选择框的选项
- AngularJS简单的ng-repeat预加载器
- 在AngularJS中,当ng-repeat下的用户列表中的一个复选框被选中时,显示一个删除按钮的简单方法
- AngularJS:自定义迭代/数据转换和分组…当简单的ng-repeat只是won'
- 在ng-Repeat (>5)上的角简单过滤器
- 不能简单地使用 ES6 承诺来更新 ng-repeat 中的数据