Функция пользовательского фильтра AngularJS
Внутри моего контроллера я хотел бы отфильтровать массив объектов. Каждый из этих объектов представляет собой карту, которая может содержать строки, а также списки
Я пробовал использовать формат $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')
. Все примеры, которые я нашел в сети до сих пор, имеют статические критерии поиска внутри функции, они не передают объект критериев и не проверяют каждый элемент массива.
Ответы
Ответ 1
Вы можете использовать его следующим образом:
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;
};
};
Ответ 2
Вот пример того, как вы будете использовать filter
в своем JavaScript-коде AngularJS (а не в HTML-элементе).
В этом примере у нас есть массив записей Country, каждый из которых содержит имя и трехзначный код ISO.
Мы хотим написать функцию, которая будет искать в этом списке запись, которая соответствует определенному 3-символьному коду.
Вот как мы это сделаем, не используя 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.
Надеюсь, что это поможет.
Ответ 3
Кроме того, если вы хотите использовать фильтр в контроллере так же, как вы это делаете:
<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
{{ item }}
</div>
Вы можете сделать что-то вроде:
var filteredItems = $scope.$eval('items | filter:filter:criteriaMatch(criteria)');