Иногда возникают задачи, связанные с реализацией презентационной логики. В качестве примера рассмотрим реализацию логики формы Заказа при изменении статуса заказа на “Оплаченный”:
- сделать поле “Дата оплаты” обязательным при переводе Заказа в статус “Оплаченный” (до сохранения);
- нужно исключить возможность изменять любые поля, кроме поля “Дата отгрузки” после перевода в статус “Оплаченный” - следовательно, их нужно заблокировать;
- после списания товара нужно убрать валидацию с Содержимого заказа, т.к. необходимого объема товара на складах может уже не быть;
- необходимо отписаться от обзервера на товар (Цена с налогом), чтобы цена товаров уже не менялась (цену товаров в конкретном заказе стоит фиксировать как минимум в момент подтверждения оплаты заказа, оптимально - когда выписывается накладная по заказу).
С учетом данных изменений, форма приобретет законченный в отношении события оплаты заказа вид.
Условные валидаторы
Для того, чтобы валидатор на обязательность поля “Дата оплаты” срабатывал не всегда, мы должны отслеживать Статус заказа. Для таких ситуаций аддон ember-cp-validations позволяет настраивать условия работы валидатора. Реализуем этот механизм на примере валидации поля order.paymentDate:
app → mixins → regenerated → models → i-i-s-shop-order.js
Нам нужно добавить сюда один из встроенных валидаторов - валидатор на обязательность значения - presence (полный список доступных валидаторов аддона можно посмотреть тут - панель Classes):
Если мы оставим его в таком виде, то валидация срабатывать будет всегда. Поэтому добавим условие валидации:
Проверим, как работает валидатор на примере Заказа 1:
Если статус заказа перевести в “Оплаченный”, то валидатор будет срабатывать:
Все работает корректно.
Самостоятельно настройте валидацию поля “Дата и время отгрузки” формы редактирования Накладной: поле обязательно для заполнения, если накладная имеет статус “Отгруженная”
Блокировка полей формы
Наиболее простой и эффективный способ изменения внешнего вида форм - это настройка шаблона. Ранее мы уже меняли элементы шаблона, настраивая режим полей “только для чтения” в статичном (постоянном) режиме. Теперь для части полей нам необходимо настроить динамическую блокировку: поля должны блокироваться только в том случае, когда заказа имеет статус “Оплаченный” и не осталось никаких несохраненных изменений. Блокировать будем всю форму целиком, так как Оплаченный заказ нельзя отменить или вновь сделать новым.
Добавим в модель Заказа новое вычислимое свойство isPaid:
app → models → i-i-s-shop-order.js
Настройку режима "только для чтения" применительно ко всей форме можно также осуществлять через свойство readonly в контроллере соответствующей формы (по умолчанию она имеет значение false, её можно видеть в шаблоне изначально). Однако, нам понадобится делать проверку на уровне модели, поэтому мы добавляем для этих целей отдельное свойство непосредственно в модели.
Далее нам нужно присвоить значение свойства модели isPaid свойству readonly для всех полей формы - по умолчанию оно имеет значение false (разрешено для редактирования). В качестве примера рассмотрим изменения для поля status:
app → templates → i-i-s-shop-order.hbs
Проверим, как работает блокировка полей на примере Заказа 1:
Переведем в статус “Оплаченный” и сохраним:
Все работает корректно.
Самостоятельно настройте:
- отключение валидации на форме Заказа с использованием нового свойства модели isPaid. При возникновении трудностей обратитесь к пункту “Условные валидаторы” и документации по аддону;
- скройте кнопки “Сохранить” и “Удалить” для формы редактирования заказа в состоянии “Оплачено”.
Условное поведение обзервера
До сих пор обзервер на обновление срабатывал каждый раз при загрузке формы, на которой он работает. В частности, если мы меняли цену товара и обновляли страницу заказа, то обзервер “подхватывал” новую цену и изменял все поля, связанные с ценой товара. Проверим данное поведение на примере Заказа 2:
- Изменим цену товара "Монитор Samsung C24F390FHI"
- Проверим состояние Заказа 2 (корректное поведение - форма заблокирована, цена с налогом у данного товара - 9900 руб.)
Как мы видим, блокировка снята, а цена товара изменилась. В нашем случае такое поведение недопустимо, так как цена товара после оплаты на форме заказа меняться не может. Кроме того, снятие блокировки объясняется тем, что поле изменяется автоматически, а значит на заблокированной форме появляются несохраненные изменения, инициированные программно - а это одно из условий блокировки.
Ограничим срабатывание обзервера на пересчет Цены с налогом в детейле на форме редактирования Заказа:
app → models → i-i-s-shop-order-item.js
Так как все остальные обзерверы на форме связаны со значением поля “Цена с налогом”, то, остановив срабатывание этого обзервера, мы “отключим” и все остальные.
Проверим внесенные изменения на примере Заказа 2:
Все работает корректно.
Самостоятельно настройте блокировку формы заказа для статуса “Отмененный”.
Подсказка: можно расширить функционал существующей блокировки для статуса “Оплаченный” (isPaid) до общего врианта isBlocked.
Итог
В процессе внесенных в данной главе изменений мы настроили поведение формы редактирования Заказа в соответствиями с требуемой логикой. В результате форма “Заказ” приобрела вид, с которым комфортно было бы работать потенциальному пользователю.
Итоговое приложение размещено в репозитории: стадии до и после работы, скрипт на создание структуры базы данных, приложение со всеми доработками (кроме самостоятельных заданий).
Самостоятельная работа
Вы можете выполнить следующие доработки в приложении самостоятельно для более полной реализации функционала приложения:
- запретить создание Накладной пользователем (убрать кнопку “Добавить” в списковой форме Накладные);