2014-03-12 54 views
8

我想知道,如果可能的话,扩展Angular的输入指令?我想将一些侦听器附加到页面上的所有输入字段。我认为你可以用$provide.decorate来装饰现有的模块,但我不知道如何用指令(更准确地说是输入指令)来做到这一点。AngularJS:扩展输入指令

那么,有谁能把我推向正确的方向吗?一些例子?

编辑

这里是我的指导,我到目前为止有:

angular.module('onFocusBlur'). 
directive('onFocusBlur', ["$rootScope", function($rootScope) { 
    return { 
    restrict: "A", 
    link: function(scope, elem, attrs) { 
     elem.bind('focus',function() { 
      scope.$apply(function() { 
      $rootScope[attrs.onFocusBlur] = true; 
      }); 
     }); 
     elem.bind('blur',function() { 
      scope.$apply(function() { 
      $rootScope[attrs.onFocusBlur] = false; 
      }); 
     }); 
    } 
    }; 
}]); 

在我看来,我可以这样将它添加到输入字段:

<input type="email" ng-model="email" on-focus-blur="repositionNavBar"> 

缺点是,对于每个输入字段,我必须在代码中手动添加此侦听器。因此,改变现有的输入指令将包括这个监听器是很有用的。

+0

你在说什么类型的听众?你能否详细说明一下。 –

+0

[Extensions Angular Directive]的可能的重复(http://stackoverflow.com/questions/17005122/extending-angular-directive) –

+0

我添加了一些代码与我现有的指令 – 23tux

回答

0

您可以轻松地扩展任何指令 - 包括输入指令。 Here是向指令添加类的快速示例。

+9

你没有扩展任何东西,你正在添加一个单独的指令。有效地创建代码OP正试图避免。 –

18

这里是你如何能装点内置的角度input指令,与$provide.decorator你自己提出了一个简短的依据。

app.config(function ($provide) { 

    // Suffix is "Directive" for decorating directives. 
    // $delegate refers to the original directive definition. 
    $provide.decorator('inputDirective', function ($delegate) { 

    // When decorating a directive, $delegate is an array containing 
    // all of the directives of the same name. 
    // We're interested in the first in this case. 
    var directive = $delegate[0]; 

    // Store a reference to the original directive linking function. 
    var link = directive.link; 

    // Hook into the compile phase of the directive. 
    directive.compile = function() { 

     // The function returned by compile is your new link function. 
     // Or 'postLink', to be exact. 
     return function (scope, el, attrs) { 

     // Run the original link function. 
     link.apply(this, arguments); 

     // Your new listener function 
     function listener (e) { 
      console.log(e); 
     } 

     // Set up your listener(s). 
     el.bind('blur', listener); 
     el.bind('focus', listener); 
     }; 
    }; 

    // Return the decorated original ($delegate). 
    return $delegate; 
    }); 

}); 

优点这种方法的,因为我看到它:

  1. 这比增加另一指令,以增加行为更加干燥。
  2. 这是一个实际第三方行为的延伸。
  3. 大部分情况下,您不需要知道您正在装修的指令(或服务)的内部实现。

这里有一个jsBin:http://jsbin.com/yafecinu/2/edit

我建议你看一看this article,即去深入的装饰指令。本文涵盖的内容不仅包括连接阶段,还包括控制器和预连接DOM操作。非常好的阅读!

+0

这是要走的路,但自从Angular 1.3以来,您需要使用预链接: 'var link = directive.link.pre;' – Scraph

+0

我遇到了使用angular-bootstrap 1.1.1的问题,使用datepickers和我应用了使用此代码的自定义装饰器。我认为更好的解决方案是使用旧的编译函数,而不是保存/调用旧的预链接函数。无论如何,它解决了我的问题。 –

+0

@JosephHelfert完全取决于你想偏离原始指令的距离。如果这很简单,你可以使用链接/控制器。如果你需要更多的细粒度控制,那么使用旧的编译功能就会变得很花哨! –