2013-05-15 9 views
60

Я новичок в AngularJS, и я создаю небольшое приложение для проката автомобилей с концептуальным дизайном, которое тянет в какой-то JSON и отображает различные биты этих данных через ng -repeat, с несколькими фильтрами:AngularJS: Пользовательские фильтры и 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 против этого. Я просто не могу понять, как бы это сделать, хотя с точки зрения синтаксиса - может ли кто-нибудь помочь?

Вот мой Plunker: http://plnkr.co/edit/lNJNYagMC2rszbSOF95k?p=preview

ответ

139

Если вы хотите запустить какую-то пользовательский фильтр логики вы можете создать функцию, которая принимает элемент массива в качестве аргумента и возвращает 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 objec t (они будут работать вместе).

+14

Этот пример должен быть в документах. –

+14

Очень интересно! Фильтр можно упростить, чтобы 'возвращать car.carDetails.doors> 2;' хотя. – sp00m

+13

Конечно, может. Однако я решил более подробный вариант, чтобы сделать его более понятным как пример обучения. – mirrormx

1

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

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

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

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

документации здесь

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

28

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

<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

+3

Можете ли вы дать более одного параметра настраиваемому фильтру? – Vincent

4

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

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

Возможна ли фильтра ИЛИ вместо AND? – lostintranslation

+0

ммм ... я думаю, что лучшим вариантом является функцией, чтобы сделать это, вот пример (не работает) http://plnkr.co/edit/PNwyDKXk9RQcur8Tpp8w?p=preview лучше – alvarodoune

Смежные вопросы