https://habrahabr.ru/post/331400/- Разработка веб-сайтов
- jQuery
- JavaScript
- HTML
Одним из преимуществ строковых шаблонизаторов таких как JUST.js, jqueryTmpl или handlebarsjs перед шаблонизаторами на основе виртуального DOM дерева (VUE.js, angular) это низкий порог вхождения и простота в использовании. Ещё как мне кажется со строковыми шаблонизаторами проще интегрировать плагины для jquery.
Однако возможность реактивного связывания данных модели с шаблоном действительно удобный инструмент, и после того как я пробовал VUE.js и angular мне стало очень не хватать этого в моём любимом шаблонизаторе
JUST.JS.
В итоге я решил добавить одностороннее реактивное связывание данных в JUST.JS, а в итоге получилось
решение которое можно использовать практически с любым строковым шаблонизатором.
Начнём с простого примера
В нём мы обошлись вообще без шаблонизатора для простоты и наглядности кода. В данном примере раз в секунду в переменную присваивается новое значение. И затем justReactive за вас вносит измения в dom дерево страницы.
Библиотека justReactive добавляет следующие методы для Object каждый из которых предназначен для вставки отслеживаемого значения в разные места html кода.
- justHtml — отображение текста или html кода из переменной без какой либо фильтрации
- justText — отображение текста из переменной как текста, с преобразованием html сущностей в текст
- justClass — подставляет класс если значение отслеживаемой переменой не false
- justNotClass — подставляет класс если значение отслеживаемой переменой false
- justClassName — подставляет как класс само значение отслеживаемой переменой
- justAttr — подставляет и обновляет атрибут у элемента
Принцип действия
Следующий вызов:
model.justText('time')
вернёт вам html код который надо вставить в шаблон на то место где должна быть ваша переменная. Он избыточный, то есть помимо значения самой переменной нам приходится её оборачивать дополнительными элементами.
Так на пример justText вернёт следующий html-код:
<div id="_justReactive2" style="display: inline;" class="just-watch just-watch-text">1498115282970</div>
Такая избыточность порой мешает при вёрстке, но эта та цена которая необходима для возможности в дальнейшем менять значение прямо на странице. Путём выполнения простого присваивания.
Так же надо учитывать то что после добавления отслеживания переменной её значение подменяется на объект с гетером и сетером (
для тех кто не знает про такую возможность) и в дальнейшем при присваиваниях они вызываются, так что если вы уже используете функции гетеров и сетеров в своём коде то надо подумать над отсутствием конфликтов.
Ещё пример использования
Этот пример основан на предыдущем. Здесь мы добавили отслеживание ещё переменной model.class для изменения класса элемента и переменной model.hide для скрытия ещё одного элемента.
Недостатки подхода
У такого подхода есть ряд проблем которые нужно учитывать при работе с кодом. В следующей ситуации мы можем получить не то что хотели:
var model = {};
model.key1 = 1;
$("#time1").html(model.justText('key1'))
model = {key1:2};
В данном примере значение в dom дереве не будет обновлено так как присваивание в model = {key1:2}; фактически сначала удалило отслеживаемый нами model.key1, а потом создало новый объект model с таким же, но не тем же самым ключом key1.
Циклы и блоки шаблонов
Для изменения отдельных элементов того что мы рассмотрели достаточно. Но для работы иногда хочется при изменении одной переменной перестроить целый блок шаблона. На пример если мы отслеживаем массив и в него добавился ещё один элемент хочется перестроить весь список элементов.
Для решения этой задачи мы бы могли вставлять сразу большой блок html кода в какой то из элементов.
Но такое хоть и работает но всё же не очень удобно. Я лично для себя сделал форк шаблонизатора
just.js и добавил в него ряд дополнительных возможностей попутно вырезав то что мне казалось в нём лишнем.
Получившийся модифицированый шаблонизатор я назвал
just-template
В него я добавил конструкцию для отслеживания переменных модели которая сразу перестраивает вложенный в неё блок шаблона. При этом через замыкание доступны все переменные переданные при построении шаблона в первый раз.
<~ this.data.itemslist>
<% for(var i in this.data.itemslist){ %>
<li><%= this.data.itemslist[i].justText('name') %> - <%- this.data.itemslist[i].text %></li>
<% } %>
<~>
Добавил фильтрацию данных:
<%- text %> - с фильтрацией
<%= text %> - без фильтрации
И полностью выпилил всю асинхронность так как я это использую только на фронтенде и отсутствие асинхронности сильно упрощает код. И даёт без проблем собирать финальную страницу по кусочкам вызовами нескольких разных шаблонов.
Финальный пример с массивом и циклами и шаблоном.
Ссылки