AngularJS: пользовательские фильтры и ng-повтор


Я новичок AngularJS, и я создаю небольшое приложение proof-of-concept car hire listings, которое вытаскивает некоторые JSON и выводит различные биты этих данных через ng-repeat с помощью нескольких фильтров:

   <article data-ng-repeat="result in results | filter:search" class="result">
        <header><h3>{{result.carType.name}}, {{result.carDetails.doors}} door, &pound;{{result.price.value}} - {{ result.company.name }}</h3></header>
            <ul class="result-features">
                <li>{{result.carDetails.hireDuration}} day hire</li>
                <li data-ng-show="result.carDetails.airCon">Air conditioning</li>
                <li data-ng-show="result.carDetails.unlimitedMileage">Unlimited Mileage</li>
                <li data-ng-show="result.carDetails.theftProtection">Theft Protection</li>
            </ul>
    </article>

    <h2>Filters</h2>

    <h4>Doors:</h4> 
    <select data-ng-model="search.carDetails">
        <option value="">All</option>
        <option value="2">2</option>
        <option value="4">4</option>
        <option value="9">9</option>
    </select>

    <h4>Provider:</h4>
    Atlas Choice <input type="checkbox"  data-ng-model="search.company" ng-true-value="Atlas Choice" ng-false-value="" value="Atlas Choice" /><br>
    Holiday Autos <input type="checkbox"  data-ng-model="search.company" ng-true-value="Holiday Autos" ng-false-value="" value="Holiday Autos" /><br>
    Avis <input type="checkbox"  data-ng-model="search.company" ng-true-value="Avis" ng-false-value="" value="Avis" /><br>      

Теперь я хочу создать пользовательский фильтр в моем контроллере, который может перебирать элементы в моем ng-repeat и возвращать только те элементы, которые отвечают определенным критериям - например, я мог бы создать массив значений, на основе которых проверяются флажки "поставщик", а затем оценить каждый пункт ng-repeat против этого. Я просто не могу понять, как бы я это сделал, хотя, с точки зрения синтаксиса - кто-нибудь может помочь?

Вот мой плунжер.: http://plnkr.co/edit/lNJNYagMC2rszbSOF95k?p=preview

4 63

4 ответа:

Если вы хотите запустить некоторую пользовательскую логику фильтра, вы можете создать функцию, которая принимает элемент массива в качестве аргумента и возвращает true или false в зависимости от того, должен ли он быть в результатах поиска. Затем передайте его в инструкцию filter точно так же, как вы это делаете с объектом search, например:

JS:

$scope.filterFn = function(car)
{
    // Do some tests

    if(car.carDetails.doors > 2)
    {
        return true; // this will be listed in the results
    }

    return false; // otherwise it won't be within the results
};

HTML:

...
<article data-ng-repeat="result in results | filter:search | filter:filterFn" class="result">
...

Как вы можете видеть, вы можете связать много фильтров вместе, поэтому добавление вашей пользовательской функции фильтра не заставляет вас удалять предыдущий фильтр, использующий объект search (они будут работать вместе без проблем).

Если вы все еще хотите пользовательский фильтр, вы можете передать в модели поиска фильтр:

<article data-ng-repeat="result in results | cartypefilter:search" class="result">

Где определение для фильтра cartypefilter может выглядеть следующим образом:

app.filter('cartypefilter', function() {
  return function(items, search) {
    if (!search) {
      return items;
    }

    var carType = search.carType;
    if (!carType || '' === carType) {
      return items;
    }

    return items.filter(function(element, index, array) {
      return element.carType.name === search.carType;
    });

  };
});

Http://plnkr.co/edit/kBcUIayO8tQsTTjTA2vO?p=preview

В одном и том же фильтре ng-repeat можно вызвать несколько фильтров функций 1

<article data-ng-repeat="result in results | filter:search() | filter:filterFn()" class="result">

Один из самых простых способов исправить это-использовать $, который является поиском all.

Вот плунжер, который показывает, что он работает. Я изменил флажки на радио (потому что я думал, что они должны быть дополняющими )..

Http://plnkr.co/edit/dHzvm6hR5P8G4wPuTxoi?p=preview

Если вы хотите сделать это очень специфическим способом (вместо общего поиска), вам нужно работать с функциями в поиске.

Документация является здесь

Http://docs.angularjs.org/api/ng.filter:filter