Функція користувацького фільтра AngularJS


91

Всередині мого контролера я хотів би відфільтрувати масив об'єктів. Кожен із цих об’єктів є картою, яка може містити рядки, а також списки

Я спробував використовувати $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')цього шляху. Всі приклади, які я знайшов у мережі, поки що мають статичний пошук за критеріями всередині функції, вони не передають об'єкт критеріїв і не перевіряють кожен елемент у масиві.


3
Навіщо потрібен фільтр? Зазвичай фільтри використовують із шаблонів. Чи можете ви не просто мати просту функцію у вашому контролері, якщо ви використовуєте її лише звідти?
Ketan

замість того, щоб вручну переходити до кожного елемента масиву, я думав, що ми могли б використовувати функцію $ filter ('filter') angular (яка подбає про ітерацію кожного елемента, якщо ми просто вкажемо функцію предиката)
user2368436

Відповіді:


173

Ви можете використовувати його так: 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;
  };
};

Я не буду використовувати цю функцію kriteriumMatch з html .. як я буду викликати її зсередини контролера, це правильно? $ filter ('filter') (array, function () {return criteriaMatch (item, criteria);});
user2368436

6
Якщо ви не використовуєте його у своєму шаблоні, визначення фільтра не дає вам жодної переваги. Ви можете просто визначити просту функцію JavaScript, оскільки вона там навіть коротша. Ви можете використовувати власний filterметод в об’єкті Array:array.filter(function(item){return item.name === criteria.name;})
Tosh

У мене є функція javascript. просто хотів переконатися, що у angular не було простішого способу зробити це .. я прийму вашу відповідь. Дякую.
user2368436

2

Ось приклад того, як ви використовуєте filterв JavaScript AngularJS (а не в елементі HTML).

У цьому прикладі ми маємо масив записів Country, кожен з яких містить ім’я та 3-значний код 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.

Сподіваюся, це допомагає.


0

Крім того, якщо ви хочете використовувати фільтр у контролері так само, як і тут:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
  {{ item }}
</div>

Ви можете зробити щось на зразок:

var filteredItems =  $scope.$eval('items | filter:filter:criteriaMatch(criteria)');

6
Як варіант,var filteredItems = $filter('criteriaMatch')(items, criteria);
321zeno
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.