Наследование директив в Angular Light и другие «плюшки»

в 20:41, , рубрики: Без рубрики

Недавно после прочтения одной статьи Армина Роначера, я подумал, что неплохо было бы иметь возможность наследовать директивы и
вскоре реализовал это в своей библиотеке Angular Light (aLight).

Вообщем все наследование сводится к разбиению директивы на методы, которые в дальнейшем можно переопределить.
Вот пример al-show-slow на основе al-show, где происходит медленное появление и скрытие элемента, выглядит так:

alight.directives.al.showSlow = function(element, name, scope, env) {
    var dir = alight.directives.al.show(element, name, scope, env);  // Создание родительской директивы
    dir.showDom = function() {  // Подменяем "show"
        $(element).fadeIn(1000);
    }
    dir.hideDom = function() {  // Подменяем "hide"
        $(element).fadeOut(1000);
    }
    return dir;
}

Пример наследования al-show
Ещё один пример al-value-delay на основе al-value, где данные попадают в модель с задержкой (без повторов).

Так же тут возможно множественное наследование, но пока не было в этом необходимости.

Далее ещё несколько полезных методов:

1) Биндинг к «оторванному» DOM, т.е. тот который не в document:

tpl = $('<div al-init="i=0" al-click="i+=1">{{i}}</div>')  // Создаем кусок DOM
alight.applyBindings(null, tpl[0])  // Делаем биндинг
$('body').append(tpl)  // Для проверки добавляем к body

2) Возможность переименовывания директив, не знаю как в Angular.js, но в aLight это просто:

alight.directives.al.myKeypress = alight.directives.al.keypress

3) В Angular.js у меня иногда возникал вопрос, как вызвать свой код сразу после $digest/$apply даже если $digest сейчас в процессе обработки. В aLight вместо $digest есть ф-ия $scan, и вызвать свой код после её обработки можно так:

scope.$scan(function(){
	// do something
})

4) Статический биндинг в DOM, в aLight есть 2 способа биндинга значений в DOM:

	<a href="{{first}}">{{first}}</a>
	<a href="{{=second}}">{{=second}}</a>

Отличие в том, что во 2-м случае не происходит слежения за изменениями переменной, это удобно в качестве обычного, одноразового рендеринга.

5) Префиксы у директив. Каждая директива находится в своем «разделе»: al-if, bo-if, ui-if и т.п. Эти разделы позволяют следить за наличием директив (как в knockout.js), например если я напишу:

<div al-ifn="visible"></div>

то aLight выдаст ошибку, что такой директивы нет.

Так же я учел коментарии хабра-пользователей, перевел API aLight с underscore на camelcase, и добавил немного директив, таких как: al-keydown, al-mousedown, al-mousemove. Полный список стандартных директив можно посмотреть тут

Ещё пара моментов из сегодняшних директив:

Для al-keydown, al-mousemove и т.п., $event доступен прямо в выражении, подумал что это может быть удобно:

<input type="text" al-keydown="key = $event.keyCode" />

Директива al-focused делает двухстороннюю привязку — при установке переменной focused=true, фокус устанавливается на элемент, а при появлении фокуса на элементе, переменная устанавливается в true, при уходе фокуса аналогично.

<input type="text" al-focused="focused" />

Пример тут, это удобно для установки фокуса при загрузке страницы или в любой другой момент, но если что-то не устроило, то можно отнаследовать и изменить.

В основном — все. Замечания и предложения приветствуются.

Автор: lega

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js