Найти в Дзене
Logonok

Готовим динамическое меню из категорий

Оглавление

В предыдущей статье мы рассмотрели привязывание метаданных к данным для формирования фильтра товаров. В этот раз создадим динамическое меню из категорий.

Модель метаданных

Навигация - это отдельная модель метаданных фреймворка Evado. Она состоит из двух основных сущностей - секции и пункта.

Секция представляет собой блок навигации и содержит список пунктов. Например, боковое меню в модуле «Офис» формируется из секции под кодовым названием main.

Пункт описывает базовый элемент меню. Он может быть одним из следующих типов:

  • Переход - переход на список объектов заданного класса или по прямой ссылке.
  • Контейнер - вспомогательный элемент, который группирует дочерние пункты. Пункты контейнера могут подгружаться при необходимости, тем самым снижая нагрузку и на сервер, и на клиента.
  • Разделитель - вспомогательный элемент, который визуально разделяет соседние пункты меню.
  • Заголовок - вспомогательный элемент, который формирует заголовок для обозначения нижележащих пунктов.

Приступаем к делу

Устанавливаем и запускаем веб-приложение «Книжный магазин». Приложение можно сразу запустить через Docker или предварительно установить необходимое окружение - Node.js и MongoDB.

В декларативном фреймворке Evado навигация, так же как и другие сущности приложения (метаданные), создаются в модуле «Студия», а оперирование данными происходит в модуле «Офис».

Переходим в модуль «Студия», в меню «Секции навигации». Здесь уже создана секция main, из которой формируется боковое меню модуля «Офис».

Кроме пунктов, непосредственно описанных в метаданных, в меню модуля «Офис» могут отображаться некоторые служебные данные. Например, в режиме разработки доступен список всех классов приложения.

Находим пункт навигации «Категории товаров» и создаем в нём дочерний пункт «Динамические категории». Указываем класс «Товар» для отображения объектов на странице данного пункта.

Обратите внимание, что родительский пункт («Категории товаров»), хотя и не является контейнером - он отображает страницу со списком категорий, но все равно отображает дочерние пункты при активации.
Динамический пункт содержит настройку провайдера, который генерирует меню
Динамический пункт содержит настройку провайдера, который генерирует меню

Для того, чтобы вместо заданного пункта генерировались новые необходимо определить провайдера. Это решается через опцию {"provider":{"class":"category","view":"menu","nameAttr":"name"}}, где

  • class - класс объектов из которых будут создаваться пункты меню (обязательный параметр);
  • view - представления класса (необязательный параметр);
  • labelAttr - кодовое имя атрибута для названия пункта (необязательный параметр, если не указан используется name);
  • descriptionAttr - кодовое имя атрибута для описания страницы (необязательный параметр). Для отображения описания необходимо передать опцию {"showDescription": true}, которая по умолчанию берет данные из описания пункта.

Фильтрация объектов

Пункт меню ведёт на страницу со списком объектов заданного класса. Заголовок страницы берется из ярлыка пункта , а если он не указан, то из ярлыка класса.

Для изменения отображения объектов в списке можно выбрать представление класса. Кроме того, можно указать условие фильтрации объектов. Для этого есть опция filter.

Фильтр подобен тому, что используется в представлении класса. Его данные определяют условие выборки объектов. Но, в отличие от ярлыка, фильтр пункта меню не заменяет, а дополняет фильтр представления (если оно используется).

В нашем случае необходим фильтр товаров по категории, которую представляет динамический пункт меню. Идентификатор категории можно извлечь из параметра запроса. Тогда фильтр примет следующий вид {"filter":["id","categories",["$param","id"]]}, где

  • id - операция сравнения (равенства) идентификаторов;
  • categories - кодовое имя атрибута товара, в котором хранятся идентификаторы категорий;
  • ["$param", "id"] - выражение для получения значения идентификатора из запроса, где $param - операция получения параметра запроса, а id - название параметра.
evado-meta-navigation/Calc.js at master · mkhorin/evado-meta-navigation

Для демонстрации мы не будем учитывать вложенность категорий. При необходимости нестандартных решений всегда можно реализовать собственный фильтр, как JavaScript класс (унаследовав ObjectFilter), и подключить его через ту же опцию
{"filter":{"Class":"component/meta/filter/MyFilter"}}.

Проверка результата

Экспортируем метаданные в meta/app и переходим в модуль «Офис».

Динамические пункты меню генерируются из объектов категорий
Динамические пункты меню генерируются из объектов категорий

В меню «Категории товаров» генерируются пункты из объектов категорий. При переходе в динамический пункт отображается список товаров, которые привязаны к данной категории. Если создать новую категорию, то она появится в боком меню после перезагрузки страницы.

Готовое приложение находится в свободном доступе.