AngularJS:扩展输入指令

时间:2014-03-12 13:07:51

标签: javascript angularjs

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

那么,有人能推动我朝着正确的方向前进吗?一些例子?

修改

这是我到目前为止的指示:

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">

缺点是,对于每个输入字段,我必须在我的代码中手动附加此侦听器。因此,更改现有的输入指令以包含此侦听器将是有用的。

3 个答案:

答案 0 :(得分:18)

以下是您如何根据自己的建议使用input修饰内置Angular $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. 在大多数情况下,您不需要了解正在装饰的指令(或服务)的内部实现。
  4. 这是一个jsBin:http://jsbin.com/yafecinu/2/edit

    我建议你看一下this article,它对装饰指令有深入的了解。本文不仅涉及扩展链接阶段,还涉及控制器和预连接DOM操作。非常好读!

答案 1 :(得分:3)

请参阅this question的回答。他们讨论了几个不同的选项,将指令从使用$ provide扩展到制作具有相同名称的指令。

此外,此链接解释了一些技巧(在“扩展指令”下):https://github.com/angular/angular.js/wiki/Understanding-Directives

答案 2 :(得分:0)

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