Внутри моего контроллера я хотел бы отфильтровать массив объектов. Каждый из этих объектов представляет собой карту, которая может содержать как строки, так и списки.
Я пробовал использовать $filter('filter')(array, function)
формат, но не знаю, как получить доступ к отдельным элементам массива внутри моей функции. Вот отрывок, чтобы показать, что я хочу.
$filter('filter')(array, function() {
return criteriaMatch(item, criteria);
});
Затем criteriaMatch()
я проверю, соответствует ли каждое отдельное свойство
var criteriaMatch = function(item, criteria) {
// go thro each individual property in the item and criteria
// and check if they are equal
}
Мне нужно сделать все это в контроллере, составить список списков и установить их в области видимости. Так что мне нужно получить доступ только $filter('filter')
этим способом. Все примеры, которые я нашел в сети, имеют статический поиск критериев внутри функции, они не передают объект критериев и не проверяют каждый элемент в массиве.
источник
Ответы:
Вы можете использовать это так: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview
Как вы обнаружили,
filter
принимает функцию предиката, которая принимает элемент за элементом из массива. Итак, вам просто нужно создать функцию-предикат на основе данногоcriteria
.В этом примере
criteriaMatch
это функция, которая возвращает функцию-предикат, соответствующую заданномуcriteria
.шаблон:
<div ng-repeat="item in items | filter:criteriaMatch(criteria)"> {{ item }} </div>
объем:
$scope.criteriaMatch = function( criteria ) { return function( item ) { return item.name === criteria.name; }; };
источник
filter
метод в объекте Array:array.filter(function(item){return item.name === criteria.name;})
Вот пример того, как вы бы использовали
filter
JavaScript в своем AngularJS (а не в HTML-элементе).В этом примере у нас есть массив записей Country, каждая из которых содержит имя и трехзначный код ISO.
Мы хотим написать функцию, которая будет искать в этом списке запись, соответствующую определенному трехзначному коду.
Вот как это сделать без использования
filter
:$scope.FindCountryByCode = function (CountryCode) { // Search through an array of Country records for one containing a particular 3-character country-code. // Returns either a record, or NULL, if the country couldn't be found. for (var i = 0; i < $scope.CountryList.length; i++) { if ($scope.CountryList[i].IsoAlpha3 == CountryCode) { return $scope.CountryList[i]; }; }; return null; };
Ага, ничего плохого в этом нет.
Но вот как будет выглядеть та же функция, используя
filter
:$scope.FindCountryByCode = function (CountryCode) { // Search through an array of Country records for one containing a particular 3-character country-code. // Returns either a record, or NULL, if the country couldn't be found. var matches = $scope.CountryList.filter(function (el) { return el.IsoAlpha3 == CountryCode; }) // If 'filter' didn't find any matching records, its result will be an array of 0 records. if (matches.length == 0) return null; // Otherwise, it should've found just one matching record return matches[0]; };
Намного аккуратнее.
Помните, что в результате
filter
возвращается массив (список совпадающих записей), поэтому в этом примере мы либо хотим вернуть 1 запись, либо NULL.Надеюсь это поможет.
источник
Кроме того, если вы хотите использовать фильтр в своем контроллере так же, как и здесь:
<div ng-repeat="item in items | filter:criteriaMatch(criteria)"> {{ item }} </div>
Вы можете сделать что-то вроде:
var filteredItems = $scope.$eval('items | filter:filter:criteriaMatch(criteria)');
источник
var filteredItems = $filter('criteriaMatch')(items, criteria);