您正在寻找执行三个操作:
- 从每个项目中获取标签数组
$scope.list
- 将它们展平成一个数组
- 从此数组中获取唯一值
您可以使用纯 JavaScript 来做到这一点,但为了使事情变得更容易,我建议使用Underscore,这是一个库,可让您访问许多用于操作和检查数组、对象等的函数。
让我们从这段代码开始:
$scope.list = [
{id: 0, tags: ['tag1', 'tag2']},
{id: 1, tags: ['tag2']},
{id: 2, tags: ['tag1', 'tag3', 'tag4']},
{id: 3, tags: ['tag3', 'tag4']}
];
现在,让我们执行第一个操作:从tags
属性中获取每个对象的数组$scope.list
。Underscore 提供的pluck
方法,正是我们所需要的。
采摘 _.pluck(list, propertyName)
map 最常见用例的一个方便版本:提取属性值列表。
使用 pluck,我们可以得到以下信息:
var tags = _.pluck($scope.list, 'tags');
// gives us [['tag1', 'tag2'], ['tag2'], ['tag1', 'tag3', 'tag4'], ['tag3', 'tag4']]
现在,我们想要展平该数组。
展平 _.flatten(array, [shallow])
展平嵌套数组(嵌套可以到任何深度)。如果您通过浅层,则数组将仅展平一个级别。
tags = _.flatten(tags);
// gives us ['tag1', 'tag2', 'tag2', 'tag1', 'tag3', 'tag4', 'tag3', 'tag4']
最后,您只需要每个标签的一个实例。
别名 _.uniq(array, [isSorted], [iterator])
:unique
生成数组的无重复版本,使用 === 来测试对象是否相等。如果您事先知道数组已排序,则为 isSorted 传递 true 将运行更快的算法。如果要基于转换计算唯一项,请传递迭代器函数。
tags = _.unique(tags)
// gives us ['tag1', 'tag2', 'tag3', 'tag4']
我们可以将它们与 Underscore 的有用chain
方法结合在一起,将它们链接在一起。让我们在返回唯一标签的范围内创建一个函数:
$scope.uniqueTags = function() {
return _.chain($scope.list)
.pluck('tags')
.flatten()
.unique()
.value();
};
由于这是一个函数,它总是返回唯一的标签,无论我们在$scope.list
事后添加或删除项目。
现在您可以使用ng-repeat
onuniqueTags
显示每个标签:
<div ng-repeat="tag in uniqueTags()">
<label class="checkbox">
<input type="checkbox" ng-model="filter.tag" />
{{tag}}
</label>
</div>
这是一个演示此技术的工作 jsFiddle:http: //jsfiddle.net/BinaryMuse/cqTKG/