Можно ли фильтровать angular.js путем сдерживания в другом массиве?
Итак, если у меня есть массив:
$scope.letters =
[{"id":"a"},
{"id":"b"},
{"id":"c"}];
И еще один массив
$scope.filterBy = ["b","c","d"];
И я хочу, чтобы некоторые ng-repeat фильтровали $scope.letters только для элементов, которые появляются в $filterBy.
Я хочу иметь возможность сделать что-то из-за:
<span ng-repeat="{{letter in letters|filter: letter.id in filterBy }} > {{letter.id}} </span>
И пусть он печатает b, c
Я знаю, что это действительно глупый пример, но есть ли способ отфильтровать выражение angular.js на основе содержимого другого объекта массива?
Ответы
Ответ 1
Вы должны попробовать что-то вроде этого:
JS:
angular.module('Test', []);
function Ctrl($scope) {
$scope.letters = [
{id: 'a'},
{id: 'b'},
{id: 'c'}
];
$scope.filterBy = ['b', 'c', 'd'];
$scope.filteredLetters = function () {
return $scope.letters.filter(function (letter) {
return $scope.filterBy.indexOf(letter.id) !== -1;
});
};
}
Ctrl.$inject = ['$scope'];
HTML:
<div ng-repeat='letter in filteredLetters(letters)'>{{letter.id}}</div>
Вы можете попробовать живой пример.
Ответ 2
Обновление
Здесь angular модуль (на основе ответа @InviS), чтобы легко реализовать этот фильтр внутри вашего приложения angular:
filters-inArrayFilter
Здесь применяется подход angular, основанный на ответе @InviS:
Фильтр должен выглядеть следующим образом:
.filter('inArray', function($filter){
return function(list, arrayFilter, element){
if(arrayFilter){
return $filter("filter")(list, function(listItem){
return arrayFilter.indexOf(listItem[element]) != -1;
});
}
};
});
где список - это список, который вы фильтруете (этот параметр задается по умолчанию angular), arrayFilter - это массив, который вы используете в качестве фильтра, и элемент - это имя свойства для фильтрации в вашем списке.
Чтобы использовать этот фильтр, вы используете ng-repeat как:
<div ng-repeat='letter in letters | inArray:filterBy:"id"'>{{letter.id}}</div>
где inArray - фильтр, filterBy (первый аргумент этого фильтра) - это ваш массив, который будет соответствовать, и "id" (второй аргумент) - это элемент списка, который вы хотите сопоставить с массивом.
Вы можете попробовать этот живой пример с помощью подхода фильтров angular.
Ответ 3
Довольно старый, но мне это нужно, и мне пришлось немного изменить его.
Здесь мой фильтр "notInArray"
app.filter('notInArray', function($filter){
return function(list, arrayFilter, element){
if(arrayFilter){
return $filter("filter")(list, function(listItem){
for (var i = 0; i < arrayFilter.length; i++) {
if (arrayFilter[i][element] == listItem[element])
return false;
}
return true;
});
}
};
});
<md-chips ng-model="filter.SelectedValues" md-autocomplete-snap
md-require-match="true">
<md-autocomplete
md-search-text="searchFilterChip"
md-items="val in filter.Values | notInArray:filter.SelectedValues:'Id'"
md-item-text="val.Name"
md-no-cache="true"
md-min-length="0">
<span md-highlight-text="searchFilterChip">{{val.Name}}</span>
</md-autocomplete>
<md-chip-template>
{{$chip.Name}}
</md-chip-template>
</md-chips>
Я предположил, что это может быть улучшено, но не нужно в моем случае.
Надеюсь, что это поможет кому-то!