zasada v0.0.27
Zasada
Фабрика виджетов, для упрощения WEB разработки, с рендерингом HTML на сервере.
Определения
- Виджет - ecmascript class с методом run ( запускается при привязке виджета к DOM узлу ).
- Блок - DOM узел, к которому привязан виджет.
- Элемент - DOM узел потомок блока. Смысл определений блок и элемент из БЭМ методологии.
<div class="_ _Widget"> // блок, к которому првязан виджет "Widget"
<span class="_Widget-Element1"></span> // элемент виджета Widget, с названием "Element1"
<span class="_Widget-Element2"></span> // элемент виджета Widget, с названием "Element2"
</div>
// "_" - специальный класс, чтобы в один запрос к DOM найти все узлы с виджетами
// виджет
class Widget {
run() {}
}
Особенности
- Больше подходит для рендеринга HTML на сервере.
- Легко переносить виджеты из проекта в проект, достаточно перенести esmodule класс, и добавить HTML class верстку.
- Минимум обращений к DOM, один запрос document.querySelectorAll( '' ) для всех виджетов_ на странице.
- Кеширование элементов внутри контекста виджета, к DOM обращение только один раз.
- Легкое обращение из одного виджета к другому через специальный интерфейс .rel или через события.
- Dependency injection реализация, позволяющая гибко изменить - расширить функционал.
- Возможность вложенности виджетов, например когда элемент одного виджета является блоком другого
<div class="_ _Widget1 _Widget2">
<span class="_ _Widget3 _Widget1-Element _Widget2-Element">
<span class="_Widget1-Element _Widget3-Element"></span>
</span>
</div>
- Легкая возможность подгрузки по требованию кода виджетов с сервера ( Lazy ).
- Расширяемая система логирования ошибок
- Легкая навигация по коду в PhpStorm, Chrome, FireFox...
- Простая возможность передавать с сервера необходимые дополнительные действия на странице. Например после ajax запроса, просто добавляя дополнительные css классы в HTML ответ. Например, закрыть popup.
- Интерфейсы из коробки для доступа к данным в атрибутах блоков и элементов ._attr, ._attrs, ._my
- Интерфейсы из коробки для работы с событиями ._on, ._off, ._fire
- Средний размер 38 kb, 10 kb gz
Концепция
- По аналогии с DOM, CSSOM еще одна Object Model, где узлами являются DOM элементы с привязанным js функционалом.
- На определяющие привязку виджетов class значения не добавляются css свойства, для отделния функционала, и отображения.
- Один виджет не обращается к элментам другого виджета. В другом виджете раеализованы публичные методы для реализации необходимого.
- Дополнительная декларативность через HTML. Например, виджет слайдер картинок, кнопки предыдущая-следующая. Вместо того, чтобы через js создавать новые узлы DOM, в зависимости от параметров, виджет при наличии в HTML элементов кнопок отслеживает клики по ним, а при отсутствии ничего не делать.
Ошибки
Not found BlockId
DOM узел обозначен как связанный с виджетом, но не обозначен с каким.
<div class="_ _MyWidget">ok</div>
<div class="_">error</div>
<div class="_ MyWidget">error</div>
No widget class
Есть разметка в HTML, но нет определения в Linker
<div class="_ _MyWidget"></div>
// ...
oLinker.setWidgets( { MyWidget } ); // not executed
// ...
No widget prop
Попытка присвоить значение несуществующему свойству класса виджета.
// ...
class MyWidget extends Widget {
definedVar;
}
// ...
oLinker.setOpts( {
Widget: {
oProps: {
definedVar: 'value', // ok
undefinedVar: 'value' // error
}
}
} );
// ...
Element not found
Не найден элемент. Если отсутствие элемента штатная ситуация - нужно добавить "?".
<div class="_ _MyWidget">
<div class="_MyWidget-Element">
</div>
class MyWidget extends Widget {
run() {
this._el( 'Element' ); // DOM Element ok
this._el( 'NotFoundElement' ); // error
this._el( 'NotFoundElement?' ); // null ok
}
}
Element query parse
Неправильный запрос элемента
<div class="_ _MyWidget">
<div class="_MyWidget-Element">
</div>
class MyWidget extends Widget {
run() {
this._el( 'Element' ); // DOM Element ok
this._el( 'Element[]' ); // [Dom Element] ok
this._el( 'NotExistElement?' ); // null ok
this._el( 'Element]' ); // error
}
}
Rel not found
Не найден виджет. Если отсутствие виджета штатная ситуация, нужно добавить вызов canEmpty( true ).
<div class="_ _MyWidget"></div>
<div class="_ _OtherWidget"></div>
class MyWidget extends Widget {
run() {
this.rel().typeOf( OtherWidget ).find(); // object OtherWidget ok
this.rel().children().typeOf( OtherWidget ).find(); // error
this.rel().children().typeOf( OtherWidget ).canEmpty().find(); // null ok
}
}
Unknown attr cast
Не найдено определение преобразования типа данных.
<div class="_ _MyWidget" data-var="3.14"></div>
class MyWidget extends Widget {
iVar;
fVar;
run() {
this._my( { var: 'i:iVar' } ); // this.iVar = 3; ok
this._my( { var: 'f:iVar' } ); // this.fVar = 3.14; ok
this._my( { var: 'undefCast:iVar' } ); // error
}
}
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago