Create directives

Directives should be located in alight.directives.prefix, you can choose any the prefix, for example al-text ( alight.directives.al.text ), bo-text ( alight.directives.bo.text ).

A hyphen should be changed to underscores, example: <input al-my-some-directive /> it will be in alight.directives.al.mySomeDirective

The prefixes are needed in order to be able to catch the lack of used directives. For example, if you use the directive "al-texta", but it does not exists (a mistake in the name or js-file isn't loaded), then aLight will throw an exception.

An example of directive al-text, the directive is called when the binding process comes to an DOM-element

alight.directives.al.text = function(element, name, scope, env) {  // DOM-element, name - value of attribute, Scope, env - access to aLight processor
    var setter = function(text) {  // a function to set a text to the DOM-element
        $(element).text(value)
    }
    var r = scope.$watch(name, setter);  // Track to the variable
    setter(r.value);  // Set the initial value of an element.
};

Input arguments:

  • element - element of DOM
  • name - value of attribute
  • scope - current Scope
  • env - access to different options
  • env.attrName - name of attribute (directive)
  • env.attributes - list of attributes
  • env.takeAttr(name, skip=true) - take a value of the attribute, if skip=true then the attribute will skip a binding process, sample
  • env.skippedAttr() - list of not active attributes.

Attributes of directive:

  • priority - you can set priority for a directive
  • template - custom template
  • templateUrl - link to template
  • scope (true/'isolate') - to make a child scope
  • restrict = 'A', can be 'AEM', 'A' matches attribute name, 'E' matches element name, 'M' matches class name
  • init - the method is called when the directive is made, before template, scope
  • link - the method is called after template, scope
  • anyAttr - you can make a custom attribute, look. directive preprocessor
alight.directives.al.stop = {
    priority: -10,
    template: '<b></b>',
    scope: true,
    init: function(element, name, scope, env) {
        return {
            owner: true
        };
    },
    link: function(element, name, scope, env) {
    }
};

If the directive will return the flag owner, then the process of binding will miss child DOM-elements, it is necessary for the directives which are themselves controlled subsidiary of DOM, such as al-repeat, al-controller, al-include.

return { owner:true }

Inheritance of directives

If you want make inheritance of a directive, you need call a parent directive after that you can replace methods of the directive. For example, al-value has a few methods:

  • onDom - binding to DOM
  • updateModel - updateing the model
  • watchModel - $watch model
  • updateDom - updateting DOM
  • initDom - set first value to DOM, updateDom(init_value)
  • start - It's called when the directive is ready

Make a directive al-value with deferred updating of model:

alight.directives.al.valueDelay = function() {
    var dir = alight.directives.al.value.apply(null, arguments);  // make the directive
    var oldUpdate = dir.updateModel;  // an old method for update the model
    var timer = null;
    
    dir.updateModel = function() {  // change th method
        if(timer) clearTimeout(timer);
        timer = setTimeout(function() {
            timer = null;
            oldUpdate();  // call the default method for update the model
        }, 500);
    }
    return dir;
}

Samples of inheritance

Создание директив

Директивы нужно помещать в alight.directives.prefix в зависимости от префикса, например al-text ( alight.directives.al.text ), bo-text ( alight.directives.bo.text ).

Дифисы нужно заменять на подчеркивания, пример: <input al-my-some-directive /> будет в alight.directives.al.mySomeDirective

Можно добавить любой префикс / (name space): alight.directive.ns = {};

Префиксы нужны для того чтобы можно было отловить отсутствие используемых директив. Например если использовать диретиву "al-texta", а её не существует (опечатка или js файл не загрузился и т.п.), то будет выведена ошибка.

Пример диретивы al-text, директива вызывается когда процесс привязывания доходит до DOM-элемента с атрибутом "al-text".

alight.directives.al.text = function(element, name, scope, env) {  // DOM-элемент, name - Значение атрибута, Scope, env - Доступ к обработчику aLight
    var setter = function(text) {  // Запись текста в DOM элемент
        $(element).text(value)
    }
    var r = scope.$watch(name, setter);  // Устанавливаем слежение за выражением, при изменении будет вызвана ф-ия setter
    setter(r.value);  // Устанавливаем начальное значение выражения в DOM элемент
};

Входные параметры:

  • element - элемент
  • name - значение атрибута
  • scope - текущий Scope
  • env - доступ к окружению и разным параметрам
  • env.attrName - имя атрибута
  • env.attributes - список атрибутов в текущем элементе
  • env.takeAttr(name, skip=true) - получить значение атрибута, если skip=true то атрибут пропутит процесс привязки, пример
  • env.skippedAttr() - Список не активных атрибутов.

Атрибуты директивы:

  • priority - приоритет для директивы - приоритет обработки директив в пределах одного DOM елемента
  • template - установить шаблон в директиву
  • templateUrl - путь к шаблону
  • scope (true/'isolate') - создать дочерний Scope для директивы
  • restrict = 'A', искать директиву по: A - имени атрибута, E - имени элемента, M - тексту из комментария.
  • init - метод который вызывается при создании директивы, до template и scope
  • link - метод который вызывается после применения template и нового scope
  • anyAttr - вы можете сделать пользовательские аттрибуты, см. препроцессор для директив
alight.directives.al.stop = {
    priority: -10,
    template: '<b></b>',
    scope: true,
    init: function(element, name, scope, env) {
        return {
            owner: true
        };
    },
    link: function(element, name, scope, env) {
    }
};

Если директива вернет флаг owner, то процесс привязывания пропускает дочерние DOM-элементы, это нужно для директив которые сами управляют дочерним DOM, например al-repeat, al-controller, al-include.

return { owner:true }

Наследование директив

Для наследования вам нужно вызвать родительскую директиву и подменить необходимые методы, например диретива al-value содержит такие методы:

  • onDom - привязка к DOM
  • updateModel - Обновление модели
  • watchModel - Привязка к модели
  • updateDom - Обновление DOM
  • initDom - Инициализация DOM, updateDom(init_value)
  • start - Вызывается после создания директивы

Делаем al-value с отложенным обновлением модели:

alight.directives.al.valueDelay = function() {
    var dir = alight.directives.al.value.apply(null, arguments);  // Создаем родительскую директиву
    var oldUpdate = dir.updateModel;  // Ссылка на родительский метод обновления модели
    var timer = null;
    
    dir.updateModel = function() {  // Подменяем метод обновления модели
        if(timer) clearTimeout(timer);
        timer = setTimeout(function() {
            timer = null;
            oldUpdate();  // Вызываем родительский метод обновления модели
        }, 500);
    }
    return dir;
}

Примеры наследования

comments powered by Disqus