Недавно после прочтения одной статьи Армина Роначера, я подумал, что неплохо было бы иметь возможность наследовать директивы и
вскоре реализовал это в своей библиотеке Angular Light (aLight).
Вообщем все наследование сводится к разбиению директивы на методы, которые в дальнейшем можно переопределить.
Вот пример al-show-slow на основе al-show, где происходит медленное появление и скрытие элемента, выглядит так:
Пример наследования al-show
Ещё один пример al-value-delay на основе al-value, где данные попадают в модель с задержкой (без повторов).
Так же тут возможно множественное наследование, но пока не было в этом необходимости.
Далее ещё несколько полезных методов:
1) Биндинг к «оторванному» DOM, т.е. тот который не в document:
2) Возможность переименовывания директив, не знаю как в Angular.js, но в aLight это просто:
3) В Angular.js у меня иногда возникал вопрос, как вызвать свой код сразу после $digest/$apply даже если $digest сейчас в процессе обработки. В aLight вместо $digest есть ф-ия $scan, и вызвать свой код после её обработки можно так:
4) Статический биндинг в DOM, в aLight есть 2 способа биндинга значений в DOM:
5) Префиксы у директив. Каждая директива находится в своем «разделе»: al-if, bo-if, ui-if и т.п. Эти разделы позволяют следить за наличием директив (как в knockout.js), например если я напишу:
Так же я учел коментарии хабра-пользователей, перевел API aLight с underscore на camelcase, и добавил немного директив, таких как: al-keydown, al-mousedown, al-mousemove. Полный список стандартных директив можно посмотреть тут
Ещё пара моментов из сегодняшних директив:
Для al-keydown, al-mousemove и т.п., $event доступен прямо в выражении, подумал что это может быть удобно:
Директива al-focused делает двухстороннюю привязку — при установке переменной focused=true, фокус устанавливается на элемент, а при появлении фокуса на элементе, переменная устанавливается в true, при уходе фокуса аналогично.
В основном — все. Замечания и предложения приветствуются.
вскоре реализовал это в своей библиотеке 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" />
Пример тут, это удобно для установки фокуса при загрузке страницы или в любой другой момент, но если что-то не устроило, то можно отнаследовать и изменить.В основном — все. Замечания и предложения приветствуются.