Show an aggregated list in angularjs

后端 未结 2 2050
野性不改
野性不改 2020-12-30 05:24

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 (

2条回答
  •  情歌与酒
    2020-12-30 06:30

    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

    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.

    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 tags property for each object in $scope.list. Underscore provides the pluck method, which is just what we need.

    pluck _.pluck(list, propertyName)

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

    Using pluck, we can get the following:

    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.

    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.

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

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

    $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.list after the fact.

    Now you can use ng-repeat on uniqueTags to show each tag:

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

提交回复
热议问题