在angularjs中显示聚合列表

Joe*_*csy 14 javascript angularjs

在我的模型中,我有类似的数据:

$scope.list = [{id:0,tags:['tag1','tag2']},{id:2,tags:['tag2']}};
Run Code Online (Sandbox Code Playgroud)

我想用复选框显示标签列表(包含'tag1'和'tag2'的唯一值).希望像:

<div ng-repeat="tag in list.tags">
    <label class="checkbox">
        <input type="checkbox" ng-model="filter.tag" />
        {{tag}}
    </label>
</div>
Run Code Online (Sandbox Code Playgroud)

如果我硬编码列表,我知道如何根据检查过滤主列表,而不是如何自动生成唯一标记列表.

Mic*_*ley 27

您正在寻求执行三项操作:

  • 从中获取每个项目的标签数组 $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']}
];
Run Code Online (Sandbox Code Playgroud)

现在,让我们执行第一个操作:从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']]
Run Code Online (Sandbox Code Playgroud)

现在,我们想要展平该阵列.

弄平 _.flatten(array, [shallow])

展平嵌套数组(嵌套可以是任何深度).如果传递浅,则数组将仅展平一个级别.

tags = _.flatten(tags);
// gives us ['tag1', 'tag2', 'tag2', 'tag1', 'tag3', 'tag4', 'tag3', 'tag4']
Run Code Online (Sandbox Code Playgroud)

最后,您只需要每个标记的一个实例.

uniq _.uniq(array, [isSorted], [iterator])别名:unique

生成数组的无副本版本,使用===来测试对象相等性.如果您事先知道数组已排序,则为isSorted传递true将运行更快的算法.如果要基于转换计算唯一项,请传递迭代器函数.

tags = _.unique(tags)
// gives us ['tag1', 'tag2', 'tag3', 'tag4']
Run Code Online (Sandbox Code Playgroud)

我们可以将这些与Underscore的有用chain方法结合在一起,将它们连接在一起.让我们在范围上创建一个返回唯一标记的函数:

$scope.uniqueTags = function() {
  return _.chain($scope.list)
    .pluck('tags')
    .flatten()
    .unique()
    .value();
};
Run Code Online (Sandbox Code Playgroud)

由于这是一个函数,因此无论我们在$scope.list事后添加还是删除项目,它都将始终返回唯一标记.

现在,您可以使用ng-repeaton uniqueTags来显示每个标记:

<div ng-repeat="tag in uniqueTags()">
  <label class="checkbox">
    <input type="checkbox" ng-model="filter.tag" />
    {{tag}}
  </label>
</div>
Run Code Online (Sandbox Code Playgroud)

这是一个工作的jsFiddle,演示了这种技术:http://jsfiddle.net/BinaryMuse/cqTKG/