@maxprof
Студент

Нужно ли делать фильтр для коллекции в Angular?

Здравствуйте, помогите понять процесс реализации сортировки(фильтрации) товаров в интернет магазине на Ангуляре.
Скажем так, есть массив или БД из которой я вывожу данные (название, цена, категория и тд..)
Нужно что-бы у пользователя была возможность отфильтровать список товаров скажем по цене, или в инпут он вводит нужное название и ему выводятся товары в соответствии с его запросом.
Так вот, в ангуляре это делается достаточно просто,
Вот я вывожу список товаров
<tr ng-repeat="product in products  | filter:query | orderBy:predicate | orderBy:price"> 
						<td> {{ product.title }} </td>
						<td> {{ product.price}} </td>
						<td> {{ product.description }} </td>
						<td> {{ product.mutch }} </td>
						<td> {{ product.state }} </td>
					</tr>

И тут я его фильтрую по имени
Tittle: <input type="text" ng-model="query.title" class="form-control">

Или например по любому другому параметру например селектом
<select id="bedroom-filter" ng-model="query.mutch">
               <option value>All</option>
               <option value=1>1</option>
               <option value=2>2</option>
               <option value=3>3</option>
             </select><br />

Мне посоветовали не делать фильтрацию таким образом, а реализовать вывод нужгой коллекции в контроллере или сервисе, но тогда у полозователя не будет возможности сделать что-то самому. Можете обьяснить в чем вред таких манипуляций? Заранее спасибо!
  • Вопрос задан
  • 304 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
но тогда у полозователя не будет возможности сделать что-то самому


Я уже вам написал в комментариях к другому вопросу но продублирую. Когда пользователь выбирает какой-то другой вариант сортировки или фильтрации, мы просто уведомляем контроллер об этом. Тот уже будет просить сервисы что бы тот предоставил данные согласно нашим новым условиям. Сервис все это сделает и вернет нам данные в контроллер. Мы чуть чуть может еще подготовим данные под наше представление и выплюнем во view (по сути данные попадают в $scope). Далее за счет дата биндинга view реагирует на изменение состояния данных и подстраивается под них согласно вашему описанию (все эти ng-repeat и т.д. Не спроста шаблоны в ангуляре называют декларативными).

Это собвенно и есть MVC, при таком подходе нашему view будет глубоко плевать на реализацию фильтрации, а нашей модели (логике по работе с данными) плевать на то как эти данные выводятся. А контроллер будет лишь посредником который будет знать как эти два слоя связываются друг с дружкой.

updated

Решил сделать пример, на который буду ссылаться дальше:

Пример

А теперь немного поясню зачем вообще так загоняться и когда допустимо фильтровать все в контроллере или вообще во вью, что бы небыло недопонимания.

Давайте представим что мы мысленно раздели наше приложение на два слоя: слой который работает с данными (M), и слой который занимается отображением этих данных пользователю (V), ну и посовместительству хэндлит взаимодействие пользователя с этим view (формы например).

Что бы упростить поддержку системы, нам надо снизить связанность этих двух слоев, сделав их максимально независимыми. Что бы изменения в одном слое не вызывали особой необходимости менять что-то в другом. Для этого мы вводим промежуточный слой - контроллеры (С). Это по сути и есть основная идея MVC. Разделяй и властвуй.

Теперь давайте задумаемся. Вот вы делаете каталог товаров по схеме аля "загружаем все данные на клиент и там все фильтруем". И все идет хорошо, мы быстро все запилили и вот данных становится уже сильно много. Настолько много что приложение начинает пидалить или же просто загрузка всех данных занимает чудовищно много времени. И вот вы приняли решение о том что фильтрация теперь будет происходить на сервере, а вы будете загружать только то что нужно сейчас.

Если у вас работа с данными уже была разделена сделать это не составит проблем. Мы просто поменяем наш ProductCatalog и заменим там методы на нужные нам. View от этого не поменяется ни сколички. Более того мы можем спокойно покрыть этот функционал быстрыми юнит тестами.

Но есть еще такая штука как "технический долг". Это когда нам надо запилить этот самый фильр в первый раз, к вам подходит клиент или менеджер и говорит "нет времеин объяснять нужно срочно еще позавчера". И у нас тут выбор:
- спорить с заказчиком о том что надо делать все правильно
- плюнуть и сделать максимально быструю реализацию, таким образом взяв у нашего кода "взаймы". То есть все работает но в будущем нам этот долг придется вернуть. Мол решили мы потом перенести фильтрацию на сервер и времени на это уйдет уже больше, так как когда-то мы сэкономили на разработке.

Словом, нужно соблюдать баланс. Иногда такие решения более чем оправданы.

Но вернемся к реалиям anuglar-а. Дело в том что когда вы используете фильтры в шаблонах, они будут дергаться на КАЖДЫЙ $digest цикл, так работает дата биндинг. То есть при относительно небольшом объеме данных у нас приложение уже будет жутко педалить. Потому использовать фильтры с коллекциями в шаблонах простительно только если вы на 100% уверены что данных пока будет мало, а потом можно будет переделать.

Как-то так. Поскольку у вас есть возможность использовать ангуляровские фильтры внутри сервисов или контроллеров, "экономный" вариант будет занимать не больше времени разработки и поддерживать такой код будет проще.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы