В предыдущей статье мы рассмотрели привязывание метаданных к данным для формирования фильтра товаров. В этот раз создадим динамическое меню из категорий.
Модель метаданных
Навигация - это отдельная модель метаданных фреймворка 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 - название параметра.
Для демонстрации мы не будем учитывать вложенность категорий. При необходимости нестандартных решений всегда можно реализовать собственный фильтр, как JavaScript класс (унаследовав ObjectFilter), и подключить его через ту же опцию
{"filter":{"Class":"component/meta/filter/MyFilter"}}.
Проверка результата
Экспортируем метаданные в meta/app и переходим в модуль «Офис».
В меню «Категории товаров» генерируются пункты из объектов категорий. При переходе в динамический пункт отображается список товаров, которые привязаны к данной категории. Если создать новую категорию, то она появится в боком меню после перезагрузки страницы.
Готовое приложение находится в свободном доступе.