我遇到的问题比最近出现的情况更多,而且我想知道最好的方法。简单说明一下:
我将数据显示在ng-repeat中,按特定项目排序。比如说它按名称排序。我的目标是在字母顺序列表中的字母处打开标题:
----A----
Abe Lincoln
Adam Smith
----B----
Barack Obama
Barry Zuckercorn
----C----
...
等等。
我尝试过的事情包括:
然而,这依赖于对数据的大量操作,并且不容易动态更改数据的排序。
post.header = true
)。然后ng-repeat可以检查它当前所在的元素是否是标题,并使用ng-if将其他内容插入到DOM中。 这感觉稍微干净但是由于ng-repeat的工作方式,标题元素必须“包含”在与ng重复元素相同的水平。例如,如果对<tr>
元素执行ng-repeat,则意味着无法为标题插入另一个<tr>
,因为特殊元素必须在内部> em> <tr>
最后,按照与上述相同的方式:
编辑:
我撰写了一篇博文here,解释了我最终如何处理这个问题 - 感谢由Ian的答案链接的Google网上论坛讨论。
答案 0 :(得分:5)
创建角度过滤器。它可以接受排序列表,按第一个字母对其进行分块,并为每个块返回一个对象,其中包含字母和以该字母开头的对象数组。
例如参见chunk by size filter here。请特别注意有关为分块值创建哈希值的讨论。
答案 1 :(得分:1)
我写了一个小指令,它监视对象并自动将$ header属性添加到列表中的第一个属性。像这样使用它:
<div ng-repeat="item in data.items | orderBy:... | filter:... as filteredItems" header-list objects="filteredItems" header="getHeader">
<div ng-show="item.$header">{{item.$header}}</div>
<div>Your normal content</div>
</div>
您可以根据需要传递构建标题的函数。该函数可以是范围中的实例方法或函数。要获得第一个字母,请在控制器中定义。
$scope.getHeader = function(item) {
return item.name.slice(0, 1);
},
当过滤器和订单发生变化时,列表会自动更新。
app.module("...").directive('headerList', function () {
return {
restrict: 'A',
scope: {
objects: '=',
header: '=' // This must be a function or instance method
},
link: function(scope) {
scope.$watch('objects', function() {
var lastHeader, currentHeader;
scope.objects.forEach(function (obj) {
// We pass obj twice, so it can be used is instance method or regular function that takes the object as argument.
currentHeader = scope.header.call(obj, obj);
// in order to display a header per type, we mark the first event of each kind as header
if (currentHeader !== lastHeader) {
obj.$header = currentHeader;
lastHeader = currentHeader;
} else {
obj.$header = null;
}
});
});
}
}
});