Фильтровать объект по дочернему массиву в операторе ng-repeat, который использует track by $index для обработки дубликатов

#javascript #angularjs

#javascript #angularjs

Вопрос:

У меня есть объект narrow.searchedMenu с 3 дочерними массивами одинаковой длины, которые я отображаю ng-repeat с помощью track by $index , потому что есть несколько повторяющихся элементов.

     <ul>
      <li ng-repeat="item in narrow.searchedMenu.description track by $index">
         {{ narrow.searchedMenu.name[$index] }},
         {{ narrow.searchedMenu.short_name[$index] }},
         {{ narrow.searchedMenu.description[$index] }}</li>
  </ul>
  

Мне нужно иметь возможность фильтровать отображаемые результаты, сохраняя только те результаты, в которых ключевое слово появляется в description . Если a description не совпадает, я хочу исключить name and short_name , а также description .

Обычно я бы использовал что-то вроде этого:

 | filter{description:'chicken'} 
  

добавляется в конец ng-repeat инструкции. Однако, похоже, это не работает track by .

Это выдает мне эту ошибку на консоли, когда я пытаюсь это сделать:

Ошибка: [$parse:синтаксис] http://errors.angularjs.org/1.5.8/$parse/syntax?p0={amp;p1=is an unexpected tokenamp;p2=16amp;p3=NaNndex |%filter{description:’chicken’}amp;p4={description:’chicken’}

Я пробовал несколько других потенциальных решений, но пока безуспешно.

Обратите внимание, что $scope он не вводится в мой контроллер, и если я попытаюсь использовать пользовательский фильтр, я получу следующую ошибку:

«Ошибка: [filter:notarray] errors.angularjs.org/1.5.8/filter/notarray?p0=0 «;

И последнее — мне сказали избегать includes , потому что он недостаточно широко поддерживается (кто-то сказал что-то об polyfill альтернативе, но я не уверен, применимо ли это к этому?).

Ответ №1:

Вы можете использовать пользовательский фильтр, прикрепленный к объекту в вашем контроллере, при условии, что вы вводите track by в качестве последнего оператора ng-repeat .

Фильтр в вашем контроллере будет выглядеть следующим образом:

 menu.chickenFilter = function(item) {
  return (item.indexOf('chicken') > -1)
}
  

ng-repeat Станет:

 <li ng-repeat="item in narrow.searchedMenu.description | filter: narrow.chickenFilter  track by $index">
         {{ narrow.searchedMenu.name[$index] }},
         {{ narrow.searchedMenu.short_name[$index] }},
         {{ narrow.searchedMenu.description[$index] }}</li>
  

Комментарии:

1. Спасибо. Хороший момент. Я думаю, что я пробовал это, но возникла проблема, потому что $scope не вводится в мой контроллер. Позвольте мне попробовать очень быстро. Обновление: ХОРОШО, да, это, кажется, проблема, это дает мне ReferenceError: $scope is not defined . Хм, я только что попытался ввести $scope в контроллер, но он по-прежнему выдает эту ошибку. Я не уверен, связано ли это с тем, что я работаю с promises и / или использую controller в качестве синтаксиса. Обязательно ли это должно быть в $scope?

2. Итак, я поместил этот фильтр в другой объект, и я думаю, что он может «видеть» его сейчас, но он выдает мне другую ошибку, с которой я столкнулся при некоторых предыдущих попытках: «Ошибка: [фильтр: notarray] errors.angularjs.org/1.5.8/filter/notarray?p0=0 »

3. Спасибо. Фрагмент кода потрясающий (и я поместил его в свой Evernote), но я все равно получаю упомянутую ошибку. Некоторые различия между фрагментом и моим заключаются в том, что у меня нет $scope и, что более важно, у меня есть объект с 3 дочерними массивами, тогда как это всего лишь массив … или, по крайней мере, я предполагаю , что это проблема из-за сообщения об ошибке с надписью «notarray»? Я не уверен…

4. Чтобы получить доступ к массиву в шаблоне, вам нужно привязать его к области видимости. И это должен быть массив для работы ng-repeat или filter. Так что это правильно. ДА.

5. Почему бы вам не убедиться, что это массив 🙂

Ответ №2:

Продолжайте с этим

  <ul>
  <li ng-repeat="item in narrow.searchedMenu track by $index" ng-if="narrow.searchedMenu[$index].description.indexOf('chicken')>-1">
     {{ narrow.searchedMenu.name[$index] }},
     {{ narrow.searchedMenu.short_name[$index] }},
     {{ narrow.searchedMenu.description[$index] }}</li>
</ul>
  

Я создал здесь плунжер

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

Комментарии:

1. Это выглядит многообещающе! Я получил эту ошибку консоли, которая Error: [$parse:syntax] http://errors.angularjs.org/1.5.8/$parse/syntax?p0=-amp;p1=is an unexpected tokenamp;p2=12amp;p3=NaNndex | ng-if=amp;p4=-if=

2. вы можете проверить, работает ли plunkr нормально, и это чистое решение. Вам нужно отладить свой код, и я думаю, что будет какая-то глупая ошибка

3. В вашем plnkr были некоторые отличия от того, что в моем вопросе. Когда я делаю ваш plnkr похожим на код в вопросе, он не работает. plnkr.co/edit/xBE21b0yhhgI6mhFz3wL?p=preview Кроме того, даже решение в вашем оригинальном plunkr не соответствовало желаемому результату, который я описал…

4. можете ли вы вставить данные json, для которых вы пытаетесь применить ng-repeat