Некоторое время назад я искал хорошие способы выполнения клиентской маршрутизации и шаблонов в ClojureScript. Я исследовал, используя несколько JavaScript-фреймворков из ClojureScript, из которых Angular, вероятно, дал наиболее многообещающие результаты, но все еще чувствовал себя немного грязным и тяжелым. Я даже реализовал свой собственный механизм маршрутизации / goog.History , основанный на Pedestal и goog.History , но что-то все равно не так
Ситуация изменилась, и сегодня есть много шума о библиотеках на основе React, таких как Reagent и Om . Я подозреваю, что React на передней панели с кучей «нативных» библиотек ClojureScript может быть лучшим способом.
Прежде чем я доберусь туда, я хочу вернуться к маршрутизации и шаблонам. Давайте посмотрим, как мы можем объединить две симпатичные библиотеки: секретарь для маршрутизации и Enfocus для шаблонов.
Допустим, у нашего приложения есть два экрана, которые заполняют всю страницу. Нет различных «фрагментов», из которых можно составить страницу. Мы хотим видеть одну страницу, когда перейдем к /#/add а другую в /#/browse . Страница «Обзор» будет немного более продвинутой и поддерживает параметры пути. Например, для /#/browse/Stuff мы хотим проанализировать «Stuff» и отобразить заголовок с этим словом.
Основной HTML может выглядеть так:
|
01
02
03
04
05
06
07
08
09
10
|
<!DOCTYPE html><html><body> <div class="container-fluid"> <div id="view">Loading...</div> </div> <script src="js/main.js"></script></body></html> |
Тогда у нас есть два шаблона.
add.html:
|
1
2
3
4
|
<h1>Add things</h1><form> <!-- boring, omitted --></form> |
browse.html:
|
1
2
3
4
|
<h1></h1><div> <!-- boring, omitted --></div> |
Теперь все, что мы хотим сделать, это заполнить элемент #view на главной странице одним из шаблонов при изменении местоположения. Полный код для этого ниже.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
(ns my.main (:require [secretary.core :as secretary :include-macros true :refer [defroute]] [goog.events :as events] [enfocus.core :as ef]) (:require-macros [enfocus.macros :as em]) (:import goog.History goog.History.EventType))(em/deftemplate view-add "templates/add.html" [])(em/deftemplate view-browse "templates/browse.html" [category] ["h1"] (ef/content category))(defroute "/" [] (.setToken (History.) "/add"))(defroute "/add" [] (em/wait-for-load (ef/at ["#view"] (ef/content (view-add)))))(defroute "/browse/:category" [category] (em/wait-for-load (ef/at ["#view"] (ef/content (view-browse category)))))(doto (History.) (goog.events/listen EventType/NAVIGATE #(secretary/dispatch! (.-token %))) (.setEnabled true)) |
Что происходит?
- Мы определяем два шаблона Enfocus.
view-addтривиален и просто возвращает весь шаблон.view-browseнемного интереснее: учитывая имя категории, измените шаблон, заменив содержимое тегаh1именем категории. - Затем мы определяем маршруты секретаря для фактического использования этих шаблонов. Все, что они сейчас делают — это заменяют содержимое элемента
#viewшаблоном. В случае маршрута «Обзор» он передает проанализированное имя категории из пути к шаблону. - Существует маршрут по умолчанию, который перенаправляет с
/на/add. Это не приводит кexample.com/add, а только устанавливает фрагмент:example.com/#/add. - Наконец, мы подключаем секретаря к
goog.History. Я не уверен, почему это не в коробке, но это достаточно просто. - Обратите внимание, что в обработчике истории есть вызов
em/wait-for-load. Это необходимо для Enfocus, если вы загружаете шаблоны с вызовами AJAX.
Вот и все, очень просто и понятно.
Обновление: исправлено размещение em/wait-for-load , большое спасибо Адриану!
| Ссылка: | ClojureScript Маршрутизация и создание шаблонов с секретарем и Enfocus от нашего партнера по JCG Конрада Гаруса в блоге Белки . |