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
    }
}5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago