В Htmlix можно использовать роутер для обновления истории, а также смены отображаемых компонентов в зависимости от переданного url.
Роутер создается в экжемпляре приложения, в поле .router
, для этого нужно использовать функцию HtmlixRouter(StateMap, routes)
которя возвращает
экземпляр HtmlixState
с новым полем .router
. Первый параметр StateMap - объект описания приложения, routes - объект с картой роутов, ключами которого
являются маршруты с которыми в будущем будет сравниваться url при изменении адреса.
Как работает router? Перед инициализацией приложения и созданием всех компонентов, роутер "смотрит" url броузера, и сравнивает его с ключами из параметра routes
затем найдя соответствие, добавляет все компоненты которых нет в поле 'first' (за исключением виртуальных массивов) в объект fetchComponents (см. выше #fetchComponents),
таким образом он перестраивает описание приложения в зависимости от текущего url, те компоненты (за исключением виртуальных массивов) для которых шаблоны отдаются на данном url,
мы указываем в поле first - они создадутся сразу после загрузки страницы, а те компоненты для которых нет шаблонов на данном адресе, будут добавлены автоматически в объект fetchComponents - роутером,
они создадутся сразу после дозагрузки шаблонов из файла templatePath: "/static/templates/index.html".(Для синхронного создания компонентов можно использовать templateVar см. ниже # Загрузка шаблонов из .js файла - templateVar).
Затем уже в ходе работы приложения мы используем функцию роутера this.rootLink.router.setRout(url)
в которой мы меняем url, роутер сравнит новый url с ключами из параметра routes
и найдя совпадение поменяет все компоненты из поля routComponent
, на те которые должны быть на данном url. В Html разметке, теги где будут меняться отображение компонентов отмечаются
data-router_carts=router
, data-router_main="router"
и т.д.
Например:
var routes = {
["/"]: {
first: ["categories", 'carts', "menu", "home_page"],
/// компоненты которые есть в html файле указываются в этом массиве, остальные будут загружены с шаблона, в fetch запросе асинхронно
routComponent: {
router_carts: "carts", //компоненты соответствующие данному роуту
router_main: "home_page"
},
templatePath: "/static/templates/index.html" // папка для загрузки шаблонов
},
["/cart/:idCart"]: { //знак : в начале слова - говорит что это параметр и сравенение не требуется, проверяет только его наличие на данной позиции
first: ["categories", 'cart_single', "menu", "home_page"],
routComponent: {
router_carts: "cart_single",
router_main: "home_page",
},
templatePath: "/static/templates/index.html"
},
["/category/:idCategory"]: {
first: ["categories", 'carts', "menu", "home_page"],
routComponent: {
router_carts: "carts",
router_main: "home_page"
},
templatePath: "/static/templates/index.html"
},
["/create/category"]: {
first: ["menu", "create_category"],
routComponent:{
router_main: "create_category"
},
templatePath: "/static/templates/index.html"
},
["/create/cart/"]: {
first: ["menu", "create_cart"],
routComponent:{
router_main: "create_cart"
},
templatePath: "/static/templates/index.html"
},
}
Выше приведен фрагмент кода из прототип SPA интернет магазина
В нем каждый ключ это один из возможных url для данного приложения. Знак : в начале слова говорит что эта часть url - является параметром и с ней сравнения не требуется, требуется только ее присутствие на данной позиции.
Также есть знак * в конце слова, говорит только сравнивать все что до звездочки, далее игнорируется например если у нас есть несколько похожих адресов /category1/json/
, /category2/json/
и т.д. мы указываем в ключе /category*/json/
и создаем один объект для описания роута, чтобы не дублировать код.
Знак *
после слеша /*
говорит не учитывать все что после слеша, то есть если роут будет ["/category/:categId/"] то он может совпать только с /category/cat_name/
, но не /category/cat_name/other/
, а если поставить звездочку после слеша то совпадет, так как будет проверяться только наличие, но не количество
Далее:
first
- имена компонентов, которые есть в html разметке на данном адресе сервера, чтобы взять из них шаблоны. Используется при первой загрузке приложения.routComponen
- объект с названиями элементов в которых переключаются компоненты на данном url, например: routComponent: { //используется в методе `.setRout(historyUrl)`
router_carts: "carts", //найдет div элемент в котором есть data-router_carts="router" и на данном historyUrl вставит в него компонент carts
router_main: "home_page" // аналогично, найдет data-router_main="router" и заменит все что в нем есть на "home_page"
},
Таким образом вызвав из любой точки this.rootLink.router.setRout(historyUrl)
- мы не только изменим историю в броузере но и поменяем компоненты отображаемые на данном url в объекте routComponent
,
метод сравнит переданный historyUrl с картой ключей объекта routes
и найдя совпадение поменяет отображаемые компоненты в соответствующих элементах страници.
Если не найдет совпадение выдаст в консоли ошибку что не можен найти url.
templatePath
- путь к файлу с шаблонами для компонентов, шаблонов которых нет на данном адресе url. Используется при первой загрузке приложения.