WebGUI Компоненты
Список компонентов это другая страница
main goal
Компонент это тег в верстке, мы не используем shadow dom.
Состояние компонента описывается в его аттрибутах, поля отображаются на аттрибуты, методы - на события.
Компонент кроме смого тега "чёрный ящик" может иметь внутри теги, или не иметь. Это зависит от реализации конкретного компонента.
При изменении аттрибутов тега Вы меняете состояние компонента - он может на это реагировать.
Компонент может сам изменять свои аттрибуты (состояние) и Ваш (внешний) код может на это реагировать.
Важно : нет ничего проще, чем задать состояние в аттрибутах и взаимодействовать с ними через , например, JS. Это позволяет без особых сложнстей взаиможействовать с таким компонентом отовсюду - из любой модели построения веб интерфейсов.
Пример компонента
Вы начинаете свой модуль на JS так:
define( [ "./comp_helpers" , // NEED "static/vendor/agui/aplib", // NEED "./markdown", // for MD ], function(helpers, _ , markdown){ markdown = exports; // hack ... CJS vs AMD alight.directives.ap = alight.directives.ap || {}; ..........
Далее я опишу для примера компонент редактирования значений на месте. Вот его состояние, которое описывается аттрибутами.
* ap-editinplace="" // активация компонента
* eip-active="true|false" // вход: активирован ли редактор , ручное управление
* eip-format="text|html|markdown" // вход: как реагировать на контент text vs html vs markdown
* eip-event="SOME ON END EDIT EVENT NAME" // вход/выход: читается при старте, имя сигнала который сигналит при установке значения
* eip-lines="1" // вход: число строк в редакторе // читается при старте
* eip-onclick="false|true" // вход: реагировать ли на click (читается только при старте)
* eip-value="**blabla**" // выход: значение, результат редактирования
* // вход: при MD формате если при инициализации здесь значение - им инициализируется компонент, иначе - внутренним содержимым
следим за аттрибутами
//свойства за которыми следим var propertyes = { 'eip-active': function(v){ // либо активация либо норм состояние if(v==='true'){ // покажем редактор activate.apply(element); // this = element }else{ // скроем редактор $(element).blur(); } }, 'eip-event': function(v){ // имя события, которое генерировать при окончании редактирования s.eventName = v; }, 'eip-lines': function(v){ s.lines = v; }, 'eip-format':function(v){ s.format = v; }, 'eip-onclick':function(v){ s.needOnClick = v==='true'; }, 'eip-value':function(v){ if(s.format=='text') $(element).text(v); else if(s.format=='html') $(element).html(v); else if(s.format=='markdown'){ $(element).html( markdown.toHTML(v) ); s.editinplacetext = v; } } };
Шаблон компонента
Код компонента в самом своём начале выглядит так. Совсем не сложно.
if(typeof exports == 'undefined') exports ={}; define( [ "static/vendor/agui/comp/comp_helpers" , // NEED "static/vendor/agui/aplib", // NEED ], function(helpers, _ ){ // это надо, чтобы не облажаться если вдруг кто-то загрузит не правильно модули // а там не будет словаря в который кладут директиву, // строка не обязательна, ведь этот словарь создаётся в aplib alight.directives.ap = alight.directives.ap || {}; /* * тут описываем параметры будущего и его свойсва и * и их значение, * указываем работают ли они только при инициализации или в процессе все жизни компоента * и указываем читаются ли они компонентом , записываются ли или то и другое сразу. * * */ alight.directives.ap.SOME_COMP_NAME = function(element) { var elem = $(element); var s = alight.Scope(); $(element).data('eip-s3',s); s.lines = 2; s.bgcolor = 'white'; // todo make as prop s.eventName = 'Edit'; s.format='text'; s.needOnClick = null; //свойства за которыми следим и реагируем var propertyes = { 'PREFIX-PROP_NAME': function(v){ // реагруем на изменение аттрибута компонента }, }; // инициализируем компонент // здесь настраивается волшебство, которое следит за требуемыми аттрибутами // и вызывает при их хзменении требуемые калбеки initAGUIComponent(element, s, propertyes); } } );
Как использовать такие компоненты
Код html
<div ap-editinplace="" eip-active="{{nodes[nodeid].titleEditMode}}" eip-event="EditEvent" eip-lines="3" eip-format="markdown" eip-onclick="false" eip-ondblclick="true" eip-value="{{nodes[nodeid].title}}" ap-listen="EditEvent :: nodes[nodeid].setTitle($evt.target.attributes['eip-value'].value); nodes[nodeid].titleEditMode = 'false'; " ></div>
Здесь используется не просто указание значений а еще и автоматическая установка значений аттрибутам из AL, например {{nodes[nodeid].title}} или {{nodes[nodeid].titleEditMode}}.
Здесь видно, что можно смешивать аттрибуты состояния компонента с дополнительной логикой в директиве ap-listen, которая в рамках AL scope выполняет код,
в момент получения события на элементе.
Код JS для инициализации компонента
Код JS Зависит от используемого вами фреймворка.
Используете Angular Light - кода инициализации не надо. компонент Инициализируется сам, т.к. функция инициализации компонента распознаётся как директива AL
Используете JQuery - вставтье в конец страницы скрипт
<script> $('[ap-editinplace]').each(function(i,e){alight.directives.ap.editinplace(e)}); </script>
не используете jquery, а только native - тогда код немного длиннее
Array.prototype.slice.call(document.querySelectorAll('[ap-editinplace]')).forEach(function(e){alight.directives.ap.editinplace(e)});
для вашего случая надо подставить вместо ap-editinplace метку вашего компонента, а вметсто alight.directives.ap.editinplace путь до функции инициализации
Comments
Comments powered by Disqus