Pull to refresh

Comments 7

Что мешает делать наследование директив подобным образом?
var dir = { // объект директивы };
app.directive("MyDir1", function(){
    return dir;
});
app.directive("MyDir2", function(){
   var dir2 = angular.copy(dir);
   dir2.template="..."; //переопределение чего либо
   return dir2;
});

Но название Angular Light очень понравилось, я уж подумал google новую версию angular выпустил, пока я спал. :)
Можно, но не очень удобно: как отнаследовать MyDir2, что если MyDir1 изменится, как на счет стандартных директив? Можно сделать более удобные обертки, но все таки неплохо было бы иметь поддержку на уровне фреймворка.
как отнаследовать MyDir2, что если MyDir1 изменится

Ну здесь все просто, нужно вынести var dir2 = angular.copy(dir); за определение директивы, и повторить наследование.
как на счет стандартных директив

Стандартные директивы хорошо спроектированы, и не думаю что у кого-то возникнет необходимость в их переопределении. Но если все же возникнет, есть исходники.
Можно глобально директиву и не хранить, ее можно достать через `$injector`
app.directive("MyDir1", function(){
    return dir;
});
app.directive("MyDir2", function(MyDir1Directive){
   var dir2 = angular.copy(MyDir1Directive);
   //...
   return dir2;
});

Кстати, стандартные тоже доступны, можно переопределять методы и в них
Кстати, стандартные тоже доступны, можно переопределять методы и в них

Можете привести пример?
Начну с того, что стандартные директивы и так хорошие, переопределять их не вижу смысла. Но в прошлых версиях Angular был баг в директиве <a></a> и для его исправления пришлось ее пропатчить:

myApp.run(function(aDirective) {
    "use strict";
    aDirective[0].compile = function(element, attr) {
        // turn <a href ng-click="..">link</a> into a link in IE
        // but only if it doesn't have name attribute, in which case it's an anchor
        if (!attr.href) {
            attr.$set('href', '');
        }
        return function(scope, element) {
            element.bind('click', function(event){
                // if we have no href url, then don't navigate anywhere.
                if (!element.attr('href')) {
                    event.stopPropagation(); // <- не хватало этой строчки
                    event.preventDefault();
                }
           });
       };
    };
});


Еще так можно делать свои шаблоны для директив из библиотеки ui-bootstrap без сборки специальной версии со своими шаблонами:

myApp.directive('myDatepicker', function(datepickerDirective) {
    "use strict";
    return angular.extend({}, datepickerDirective, {
           templateUrl: 'partitials/datepicker.html' // custom datepicker template
    });
});


Но это, как видите, необычные случаи, в обычной ситуации так делать не приходится. Если вам нужно переиспользовать логику стандартной директивы, добавьте ее в поле requires, тогда вы получите доступ к ней через linkFunction. Чтобы реализовать input с задержкой как в вашем примере, нужно написать такую директиву:

myApp.directive('inputDefer', function($timeout) {
     return {
         requires: 'ngModel',
         link: function(scope, elm, attrs, ngModelCtrl) {
              var $setViewValue = ngModelCtrl.$setViewValue,
                  delay = attrs.inputDefer;
              ngModelCtrl.$setViewValue = function() {
                    var args = arguments;
                    $timeout(function() {
                       ngModelCtrl.$setViewValue.apply(ngModelCtrl, args);
                    }, 500);
              };
         }
     };
});


Но и это делается непонятно зачем, стандартная реализация ngModel имеет достаточно оптимизаций, чтобы не вызываться слишком часто, а если вы все-таки нашли такой случай, то наверно стоит завести им issue, теперь они обновляются каждую неделю и увидеть ее исправление получится достаточно скоро
Патчить директивы можно ещё следующим образом:

app.config(function($provide){
    $provide.decorator('someDirective', function($delegate) {
        $delegate.restrict = 'E';
        $delegate.controller.method1 = function(){};
        $delegate.link = function(){};
        return $delegate;
    }
})
Sign up to leave a comment.

Articles