Рад представить вашему вниманию js-фреймворк под названием ErgoJS для создания «насыщенных» веб-приложений. И да, я люблю велосипеды.
В этой статье я не буду описывать подробно сам фреймворк и коснусь лишь общих моментов, поскольку соответсвующую информацию планирую в скором времени разместить на сайте проекта.
Начнем знакомство.
Сразу хочется сказать, что ErgoJS не имеет стержневой идеи, так сказать, особой «киллер-фичи» вроде MVC, MVVM, собственного языка шаблонизации и т.п.
ErgoJS в первую очередь создавался как библиотека виджетов, но сейчас по мере взросления акцент сдвинулся в сторону построения полноценных веб-приложений.
Работа над этим фреймворком началась уже довольно давно, предназначался он для программистов, которые привыкли иметь дело с «толстым» клиентом и в одиночку клепать приложения. Но участие в команде веб-разработки, разбитой изначально на тройку специализаций `дизайнер` — `верстальщик` — `программист`, а позже на пару `дизайнер-верстальщик` и `верстальщик-программист` внесло свои коррективы. Создавать инструмент для программирования было легко и увлекательно, а вот со стилями и разметкой как-то сразу не задалось (привет и прощай IE6). Долгие совещания со командой, попытки «сделать раз и навсегда» не приносили заметных плодов и только отнимали драгоценное время. Нужно было искать другое решение. И такое продолжалось до появления CSS-фреймворков, которые, пусть и не полностью, но привели в порядок и систематизировали магию верстки, сделав ее доступной для использования простыми веб-разработчиками.
Цели и задачи
Накопление и фиксация методик, а не решений
ErgoJS состоит из двух частей: ядра и библиотеки виджетов. Пусть они и тесно связаны, но каждый имеет свое собственное назначение. Так ядро старается вобрать и систематизировать приемы и методы работы программиста и верстальщика, позволяя создавать и модифицировать виджеты, играющие роль кирпичиков веб-приложения. В самом вырожденном случае с помощью компонентов ядра можно выполнить обычную верстку страницы, используя возможности пространства имен html.
Библиотека виджетов в свою очередь содержит эталонный набор компонентов из которых строится приложение. Это меняет подход к разработке (не «создаем», а «собираем») и снижает требования к уровню подготовки программиста (не обязательно знать, как выровнять или отцентровать элементы на странице — достаточно воспользоваться нужной компоновкой). Программист может использовать входящие в состав библиотеки компоненты для создания прототипа, иногда грубого, иногда довольно точного, чтобы в дальнейшем «допилить» его до уровня готового программного продукта.
Принцип наименьшего удивления
Функции и поведение компонентов фреймворка стремятся иметь очевидное и предсказуемое поведение. Этого сложно добиться, поскольку разные люди имеют разный опыт и взгляд на то, как должны работать те или иные вещи, но обсуждение вопроса в группе специалистов позволяет решить многие проблемы.
Не делать лишнего
Если что-то можно реализовать средствами HTML или CSS, то так оно должно быть сделано. Использование JavaScript позволяет компенсировать отсутствие полной поддержки стандартов популярными браузерами (полифилы) или добавить новых возможностей, которые не попали под стандартизацию.
Когда происходит обновление спецификаций, функционал ErgoJS обновляется, так, к примеру, ожидаемая поддержка всеми браузерами flexbox-лэйаута, позволит отказаться от заметной части функционала компоновок ErgoJS, которая касается автоматического расчета размеров виджетов.
Компактность кода
Решение задач в общем виде всегда имеет один недостаток — избыточность. В этом случае должен быть либо отказ от обобщения, либо создание механизма для краткой записи операций. ErgoJS стремится идти по второму пути, но с одним правилом: «если код пишется для повторного использования, то следует применять общие формы». Во всех остальных случаях краткие формы предпочтительнее.
Особенности ErgoJS
Декларативный стиль программирования.
Когда перед программистом ставится задача, он ищет алгоритм решения и реализует его. С пользовательским интерфейсом все по-другому – решение не подразумевает алгоритма, но допускает структурную декомпозицию. В этом случае можно разбить картинку на мелкие части и решить каждую из них по отдельности, друг за другом. Но что получится, если все эти части уже имеют собственные решения и разработчику необходимо собрать их вместе, как строители собирают и возводят дом из панелей или кирпича? Меняется сам характер разработки – задумываться приходится не о том, как класть кирпич один за другим, а о том, как соединить вместе панели, где сделать проемы, как поставить перекрытия. Чтобы понять о чем идет речь, рассмотрим пару примеров.
Создаем бокс с кнопками императивно:
var box = new Ergo.widgets.Box();
var btn1 = new Ergo.widgets.Button({text: 'Кнопка 1'});
var btn2 = new Ergo.widgets.Button({text: 'Кнопка 2'});
var btn3 = new Ergo.widgets.Button({text: 'Кнопка 3'});
box.items.add(btn1);
box.items.add(btn2);
box.items.add(btn3);
И декларативно:
var box = $.ergo({
etype: 'box',
defaultItem: {
etype: 'button'
},
items: [
{text: 'Кнопка 1'},
{text: 'Кнопка 2'},
{text: 'Кнопка 3'}
]
});
На этом примере видно, что при императивном подходе мы сами последовательно создаем виджет, а при декларативном — указываем некоему «исполнителю», требуемый результат, чтобы он сделал все за нас. Естественно, чем точнее и понятнее мы опишем результат, тем лучше он будет совпадать с нашим замыслом.
В каком-то смысле ErgoJS заставляет выполнить минимальное проектирование интерфейса и только потом начинать его создание.
Виртуальное дерево виджетов (Virtual Widget Tree) и DOM
Виджеты это самостоятельные сущности или, вернее, иерархия сущностей, для которых DOM является лишь представлением. Это означает, что, хотя каждый виджет связан с определенным DOM элементом, при отображении количество, расположение и взаимосвязи между элементами не обязательно соответствуют таковым в VWT.
VWT очень похоже на Shadow DOM, но, если второй есть смесь логики и представления, то VWT это чистая логика. Это означает, что VWT может использовать Shadow DOM для оптимизации процесса рендеринга, но не является его аналогом.
// создадим виджет-кнопку
$.ergo({
etype: 'button',
components: {
icon: {
etype: 'icon',
// сделаем, чтобы иконка отображалась до текста
weight: -10,
// виджет создается, но не добавляется в DOM (это можно сделать позже)
autoRender: false
},
content: {
// оставим содержимое простым текстом
etype: '&text'
}
}
});
Иерархическое связывание данных (Hierarchical Data Binding)
В большинстве случаев структура данных соответсвует структуре элементов страницы, что, впрочем, неудивительно, поскольку данные логически связаны в рамках модели предметной области, а их отображение сохраняет эту логику, поскольку она по определению известна и понятна пользователю.
Подключая данные к виджету, они автоматически привязываются ко всем дочерним виджетам. Процессом привязки можно управлять, отключая или игнорируя связывание как для отдельных виджетов в VWT, так и для поддеревьев.
var obj = {
title: 'Тест',
datetime: '2014-11-10T12:55:00',
description: 'Loremipsum',
img: 'img/image_001.jpg'
};
$.ergo({
etype: 'box',
// привязываем данные при создании виджета
data: obj,
// компоненты
components: {
header: {
binding: 'text',
dataId: 'title'
},
content: {
// расположим элементы вертикально
layout: 'stack',
items: [{
etype: 'html:img',
// связываем данные с опцей src
binding: 'src'
}, {
binding: 'text'
dataId: 'description'
}, {
dataId: 'datetime',
// связывание можно настроить на свое усмотрение
binding: function(v) {
this.opt('text', moment(v).format('YYYY-MM-DD'));
}
}]
}
}
});
Динамическое связывание данных (Dynamic Data Binding)
Механизм связывания подразумевает влияние данных на параметры, внешний вид, состояние виджета. При динамическом связывании данные определяют структуру виджетов VWT, причем связь данных с виджетами односторонняя, т.е. изменение представления не влияет на данные, а вот изменение данных перестраивает взаимосвязи между виджетами.
var list_data = ['Африка', 'Европа', 'Антарктида', 'Азия']
$.ergo({
// создаем список UL/LI
etype: 'html:ul',
// определим элемент по умолчанию
defaultItem: {
etype: 'html:li',
// данные свяжем с опцией text
binding: 'text'
},
// указываем, что элементы виджета управляются данными
dynamic: true,
// связываем данные с виджетом
data: list_data
});
Кроме явного назначения динамического связывания для управления плоскими списками и древовидными списками, есть еще и неявное — разграничение доступа пользователя. Т.е изменять отображение страницы можно не только подгружая разные скрипты для разных прав, но и разделяя данные, которые присылает сервер.
Разделение на компоненты и элементы
На самом деле такое разделение определяет сам javascript. В нем есть два вида коллекций: Array и Object — простой массив и ассоциативный. Поэтому дочерние виджеты, которые имеют уникальное имя становятся компонентами (`components`), а те, которые имеют поряковый номер — элементами (`items`).
// кнопка с пиктограммой
$.ergo({
etype: 'button',
components: {
// компонент-пиктограмма `icon`
icon: {
etype: 'icon',
state: 'fa-cog'
},
// текстовый компонент `content`
content: {
etype: '&text'
}
},
text: 'Тестовая кнопка'
});
// список
$.ergo({
etype: 'html:ul',
defaultItem: {
etype: 'html:li',
},
items: ['Item_1', 'Item_2', 'Item_3']
});
Популярный фреймворк в качестве основы (jQuery)
Сам ErgoJS использует лишь небольшую часть возможностей jQuery, и по мере своего развития переходит на VanillaJS в критических для производительности участках. Однако, на практике jQuery значительно упрощает работу создания примесей и открывает дорогу для подключения огромного количества сторонних плагинов.
// создаем виджет-список
var w = $.ergo({
etype: 'list',
items: ['Яблоко', 'Апельсин', 'Груша']
});
// jQuery-элемент <ul> доступен через свойство el
w.el.css('color', '#f00');
и другие...
Самый лучший способ понять, что же из себя представляет `ErgoJS`, это ознакомиться с примерами на сайте.
Плюсы и минусы
К хорошим сторонам ErgoJS можно отнести:
- «Чистый» HTML, нет «лишних» атрибутов
- Приложение разрабратывается на JavaScript
- Один базовый объект — виджет
А также упомянуть о недостатках:
- Относительно невысокая скорость отрисовки
- Мало готовых решений, пока нет возможности работать в режиме конструктора
- Нет специализированной поддержки тестов
Автор: eliace