2013-05-10 3 views
2

Я новичок в AngularJS и собираю довольно базовое доказательство концепции для своего босса. Это списки для проката автомобилей, а список результатов в главной области просмотра, заполненный через внешний JSON, и панель фильтров сбоку. Вы можете увидеть Plunker я создал здесь:Ссылка на область охвата детей в фильтрах (AngularJS)

http://plnkr.co/lNJNYagMC2rszbSOF95k

Я был в состоянии успешно ссылаться на дочерние объекты/значения в моем ngRepeat:

<article data-ng-repeat="result in results | filter:search" class="result"> 
    <h3>{{result.carType.name}}, {{result.carDetails.doors}} door, &pound;{{result.price.value}} - {{ result.company.name }}</h3> 
    <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> 

... однако, я до сих пор не удалось получить доступ к дочерним объектам второго уровня в моем поисковом фильтре. Например, когда я фильтрую «тип автомобиля» (см. Ниже), я бы хотел использовать «search.carType.name» как мой ngModel, чтобы быть как можно более конкретным, но это не так. Работа не работает, хотя использование «search.carType» отлично работает. Может ли кто-нибудь посоветовать, что я делаю неправильно?

<h4>Car type:</h4> 
    Compact <input type="checkbox" data-ng-model="search.carType" ng-true-value="Compact" ng-false-value="" /><br> 
    Intermediate <input type="checkbox" data-ng-model="search.carType" ng-true-value="Intermediate" ng-false-value="" /><br> 
    Premium <input type="checkbox" data-ng-model="search.carType" ng-true-value="Premium" ng-false-value="" /><br> 
+2

вы должны использовать фильтр: search.carType.name –

ответ

3

Ваш объект поиска заполняется правильно, но фильтр не потребляет его так, как вы ожидаете. Если посмотреть на реализацию фильтра (https://github.com/angular/angular.js/blob/master/src/ng/filter/filter.js), он, по-видимому, погрузится только в один уровень дочерних свойств, когда ему задан объект в качестве определения фильтра.

Предложение Ajay будет работать, но тогда вам понадобится связать дополнительные фильтры, чтобы разместить другие параметры. Вы можете изменить тип автомобиля и компанию, чтобы указать x.name в ng-модели, а затем изменить фильтр на filter:search.carType.name|filter:search.company.name. Если бы у вас было только небольшое количество типов параметров, я бы справился с этим так.

С другой стороны, приятная вещь о вашем нынешнем подходе заключается в том, что он прозрачный. Нет необходимости, чтобы вызов фильтра был изменен, если число параметров изменилось в другом месте. Если бы у вас было относительно большое количество таких, или если они были динамическими, я бы использовал более масштабируемый подход. Напишите фильтр FUNCTION, который потребляет объект поиска, и идет более одного уровня в глубину при сравнении детей с отфильтрованными данными.

+0

ОК, спасибо, время, чтобы углубиться в пользовательские фильтры! – ParkerDigital

+0

На самом деле вам не нужен целый пользовательский фильтр. Вы можете использовать опцию 'function' для фильтра Filter (думаем, что мы немного используем это слово?) Посмотрите здесь: http://docs.angularjs.org/api/ng.filter:filter. Вам не нужно мутировать набор, который вы фильтруете, просто дайте true или false для каждого элемента, и фильтр сделает это из коробки. Вам просто нужно дать ему функцию компаратора, которая использует ваш объект поиска для оценки каждого элемента. –

1

Вот хороший пост Антона Kropp на глубокой фильтрации объекта: FILTER ON DEEP OBJECT PROPERTIES IN ANGULARJS

Соответствующий код:

function initFilters(app){ 
    app.filter('property', property); 
} 

function property(){ 
    function parseString(input){ 
     return input.split("."); 
    } 

    function getValue(element, propertyArray){ 
     var value = element; 

     _.forEach(propertyArray, function(property){ 
      value = value[property]; 
     }); 

     return value; 
    } 

    return function (array, propertyString, target){ 
     var properties = parseString(propertyString); 

     return _.filter(array, function(item){ 
      return getValue(item, properties) == target; 
     }); 
    } 
} 

И HTML

<ul> 
    only failed: <input type="checkbox" 
        ng-model="onlyFailed" 
        ng-init="onlyFailed=false"/> 

    <li ng-repeat="entry in data.entries | property:'test.status.pass':!onlyFailed"> 
     <test-entry test="entry.test"></test-entry> 
    </li> 
</ul> 

И JSFiddle here

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