javascript 在 angularjs 中显示聚合列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14163027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:53:05  来源:igfitidea点击:

Show an aggregated list in angularjs

javascriptangularjs

提问by Joel Lucsy

In my model I have data similar to:

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

$scope.list = [{id:0,tags:['tag1','tag2']},{id:2,tags:['tag2']}};

I want to show a list of tags (contains unique values of 'tag1' and 'tag2') with checkboxes. Hopefully something like:

我想显示带有复选框的标签列表(包含“tag1”和“tag2”的唯一值)。希望是这样的:

<div ng-repeat="tag in list.tags">
    <label class="checkbox">
        <input type="checkbox" ng-model="filter.tag" />
        {{tag}}
    </label>
</div>

I know how to filter the main list based on whats checked if I hard code the list, but not how to generate the list of unique tags automatically.

如果我对列表进行硬编码,我知道如何根据检查的内容过滤主列表,但不知道如何自动生成唯一标签列表。

回答by Michelle Tilley

You are looking to perform three operations:

您要执行三个操作:

  • Get the array of tags from each item in $scope.list
  • Flatten these into a single array
  • Get the unique values from this array
  • 从每个项目中获取标签数组 $scope.list
  • 将这些展平成一个数组
  • 从此数组中获取唯一值

You can do this with pure JavaScript, but to make things easier, I would recommend using Underscore, a library that gives you access to many functions for manipulating and inspecting arrays, objects, and so forth.

您可以使用纯 JavaScript 执行此操作,但为了更轻松,我建议使用Underscore,这是一个库,可让您访问许多用于操作和检查数组、对象等的函数。

Let's start with this code:

让我们从这段代码开始:

$scope.list = [
  {id: 0, tags: ['tag1', 'tag2']},
  {id: 1, tags: ['tag2']},
  {id: 2, tags: ['tag1', 'tag3', 'tag4']},
  {id: 3, tags: ['tag3', 'tag4']}
];

Now, let's perform the first operation: get the array from the tagsproperty for each object in $scope.list. Underscore provides the pluckmethod, which is just what we need.

现在,让我们执行第一个操作:从 中的tags每个对象的属性中获取数组$scope.list。Underscore 提供了pluck方法,这正是我们所需要的。

pluck_.pluck(list, propertyName)

A convenient version of what is perhaps the most common use-case for map: extracting a list of property values.

采摘_.pluck(list, propertyName)

地图最常见用例的一个方便版本:提取属性值列表。

Using pluck, we can get the following:

使用 pluck,我们可以得到以下结果:

var tags = _.pluck($scope.list, 'tags');
// gives us [['tag1', 'tag2'], ['tag2'], ['tag1', 'tag3', 'tag4'], ['tag3', 'tag4']]

Now, we want to flatten that array.

现在,我们想要展平该数组。

flatten_.flatten(array, [shallow])

Flattens a nested array (the nesting can be to any depth). If you pass shallow, the array will only be flattened a single level.

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

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

tags = _.flatten(tags);
// gives us ['tag1', 'tag2', 'tag2', 'tag1', 'tag3', 'tag4', 'tag3', 'tag4']

Finally, you only want one instance of each tag.

最后,您只需要每个标签的一个实例。

uniq_.uniq(array, [isSorted], [iterator])Alias: unique

Produces a duplicate-free version of the array, using === to test object equality. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iterator function.

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

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

tags = _.unique(tags)
// gives us ['tag1', 'tag2', 'tag3', 'tag4']

We can combine these together with Underscore's useful chainmethod to chain these together. Let's create a function on the scope that returns the unique tags:

我们可以将它们与 Underscore 的有用chain方法结合起来将它们链接在一起。让我们在作用域上创建一个返回唯一标签的函数:

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

Since this is a function, it will always return the unique tags, no matter if we add or remove items in $scope.listafter the fact.

由于这是一个函数,它总是会返回唯一的标签,无论我们$scope.list事后添加还是删除项目。

Now you can use ng-repeaton uniqueTagsto show each tag:

现在您可以使用ng-repeatonuniqueTags来显示每个标签:

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

Here is a working jsFiddle that demonstrates this technique: http://jsfiddle.net/BinaryMuse/cqTKG/

这是一个演示此技术的有效 jsFiddle:http: //jsfiddle.net/BinaryMuse/cqTKG/

回答by Mark Rajcok

Use a custom filter to get a unique set/array of tags, suitable for use with ng-repeat:

使用自定义过滤器获取唯一的标签集/数组,适合与 ng-repeat 一起使用:

.filter('uniqueTags', function() {
    return function(list) {
        var tags = {};
        angular.forEach(list, function(obj, key) {
            angular.forEach(obj.tags, function(value) {
                tags[value] = 1;
            })
        });
        var uniqueTags = []
        for (var key in tags) {
            uniqueTags.push(key);
        }
        return uniqueTags;
    }
});

I first put the tags into an object, which automatically gives us uniqueness. Then I convert it to an array.

我首先将标签放入一个对象中,这会自动为我们提供唯一性。然后我将其转换为数组。

Use as follows:

使用方法如下:

<div ng-repeat="tag in list | uniqueTags">

Fiddle.

小提琴



The following may not do what I think you probably want/expect it to do:

以下可能不会做我认为你可能想要/期望它做的事情:

<input type="checkbox" ng-model="filter.tag">

This does not create $scope properties filter.tag1and filter.tag2on the controller scope (i.e., the scope where ng-repeat is used). Each iteration of ng-repeat creates its own child scope, so the ng-model above will create scope property filter.tagon each ng-repeat child scope, as shown in my fiddle.

这不会产生$作用域属性filter.tag1filter.tag2在控制器范围内(即,在使用NG-重复范围)。ng-repeat 的每次迭代都会创建自己的子作用域,因此上面的 ng-model 将filter.tag在每个 ng-repeat 子作用域上创建作用域属性,如我的小提琴所示。