AngularJS - 如何覆盖指令ngClick

Sim*_*cha 26 angularjs angularjs-directive angularjs-ng-click

我想覆盖指令ng-click:在每次执行ng-click之前对某些进行一些$ rootscope的更改.怎么做?

Eri*_*hen 75

每个指令都是AngularJS中的特殊服务,您可以覆盖或修改AngularJS中的任何服务,包括指令

例如,删除内置 ngClick

angular.module('yourmodule',[]).config(function($provide){
    $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
        //$delegate is array of all ng-click directive
        //in this case first one is angular buildin ng-click
        //so we remove it.
        $delegate.shift();
        return $delegate;
    }]);
});
Run Code Online (Sandbox Code Playgroud)

angular支持多个指令同名,因此您可以注册自己的ngClick指令

angular.module('yourmodule',[]).directive('ngClick',function (){
  return {
    restrict : 'A',
    replace : false,
    link : function(scope,el,attrs){
      el.bind('click',function(e){
        alert('do you feeling lucky');
      });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

查看http://plnkr.co/edit/U2nlcA?p=preview 我写了一个删除了角度内置的示例ng-click并添加了一个自定义的ngClick

  • 如何保留两个委托,但让第一个处理程序有条件地传播到内置委托? (2认同)

Buu*_*yen 30

您不能覆盖AngularJS内置指令.但是,您可以使用相同的名称定义多个指令,并针对同一元素执行它们.通过分配适合priority您的指令,您可以控制指令是在内置指令之前还是之后运行.

这个plunker展示了如何构建一个ng-click在内置ng-click函数之前执行的指令.代码也如下所示.单击链接时,自定义ng-click将首先运行,然后内置运行ng-click.

的index.html

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="jquery@1.9.0" data-semver="1.9.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.js"></script>
    <script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="MyCtrl">
    <a ng-click="alert()">Click me</a>
  </body>

</html>
Run Code Online (Sandbox Code Playgroud)

的script.js

angular.module('app', [])
  .directive('ngClick', function($rootScope) {
      return {
        restrict: 'A',
        priority: 100, // give it higher priority than built-in ng-click
        link: function(scope, element, attr) {
          element.bind('click', function() {
            // do something with $rootScope here, as your question asks for that
            alert('overridden');
          })
        }
      }
  })
  .controller('MyCtrl', function($scope) {
    $scope.alert = function() {
      alert('built-in!')
    }
  })
Run Code Online (Sandbox Code Playgroud)

  • 与JackNova一致,这个答案是不正确的.*你可以覆盖/替换所有指令,因为@ eric-chen在下面显示*这个示例方法会遇到问题 - 你不能在同一个元素上有多个指令请求隔离范围或设置模板.埃里克的方法也解决了这个问题 (2认同)