Ответ 1
Вы хотите выполнить три операции:
- Получить массив тегов из каждого элемента в
$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
. Подчеркивание предоставляет метод pluck
, который нужен именно нам.
pluck
_.pluck(list, propertyName)
Удобная версия, пожалуй, наиболее распространенного случая использования для карты: извлечение списка значений свойств.
Используя 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
_.uniq(array, [isSorted], [iterator])
Псевдоним:unique
Производит дублируемую версию массива, используя === для проверки равенства объектов. Если вы заранее знаете, что массив отсортирован, передача true для isSorted будет выполнять гораздо более быстрый алгоритм. Если вы хотите вычислить уникальные элементы на основе преобразования, передайте функцию итератора.
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
на uniqueTags
, чтобы показать каждый тег:
<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/