Угловые вложенные фильтры в контроллере

У меня есть элементы для поиска по названию (строка) или тегам (массив строк)

Предметы:

[
  {
    title: 'My title',
    tags: ['tag1', 'other']
  },
  {
    title: 'Misc',
    tags: ['tag1', 'notag']
  }
]

Я хочу, чтобы один ввод выполнялся для поиска в заголовке ИЛИ тегах

В моем шаблоне это работает хорошо:

<form>
    <input type="text" ng-model="query">
</form>

<li ng-repeat="item in items | filter:query:title | filter:query:tags">
    <p>{{item.title}}</p>
</li>

Показаны все мои элементы, и если я ввожу текст, он фильтруется по названию или тегам. пример: я набираю title, возвращается только первый элемент, а если я набираю tag1, возвращаются оба.

Теперь мне нужно иметь другую область с результатами этого фильтра поиска.

В моем контроллере/директиве я попробовал:

scope.filteredItems = $filter('filter')($filter('filter')(scope.items, {title: scope.query}), {tags: scope.query});

Но у меня нет таких результатов, что я пропустил?


person Tib    schedule 04.03.2014    source источник


Ответы (1)


Прежде всего, вы неправильно используете фильтр в своем HTML. Если вы посмотрите на документацию по фильтрам, вы см., что он ожидает выражение и компаратор. Итак, на данный момент в HTML вы передаете query в качестве выражения и title или tags в качестве компаратора, оба из которых не определены.

Поскольку вы передаете строку как выражение,

Строка оценивается как выражение, и полученное значение используется для сопоставления подстроки с содержимым массива. Будут возвращены все строки или объекты со строковыми свойствами в массиве, содержащем эту строку.

Другими словами, для запроса выполняется поиск всех свойств в каждом элементе. Вот почему он фильтрует по title и/или tags.

Затем в вашем контроллере вы передаете объект как выражение. Это делает так, что на самом деле он возвращает только элементы, в которых данный атрибут соответствует заданному значению. Однако, поскольку вы вызываете его дважды, вы фильтруете свои элементы, где ОБА title и tags соответствуют вашему query.

Есть два способа исправить это.

Если вы не возражаете против поиска query во всех полях, вы можете сделать это следующим образом. В вашем HTML замените на

<li ng-repeat="item in items | filter:query">

и в вашем контроллере замените на

$scope.filteredItems = $filter("filter")($scope.items, $scope.query);

Однако, если вы хотите искать только title и tags, это намного сложнее. См. этот пост о том, как создать собственный фильтр, который выполняет поиск по нескольким полям:

Как отфильтровать несколько значений (операция ИЛИ) в angularJS

person Lukas    schedule 04.03.2014
comment
Но как быть, если OP только хочет отфильтровать title и tags? - person Davin Tryon; 04.03.2014
comment
Спасибо за ваш ответ :) и да, я хочу фильтровать только по заголовку и тегам. Есть ли способ сохранить угловой фильтр по умолчанию только с определенными значениями? - person Tib; 04.03.2014
comment
К сожалению, угловой фильтр по умолчанию позволяет фильтровать только ВСЕ указанные вами значения, а не некоторые. - person Lukas; 04.03.2014