将DOM事件添加到Angular指令

Add DOM event to Angular directive

本文关键字:Angular 指令 添加 DOM 事件      更新时间:2023-09-26

我想将DOM事件附加到指令元素,以便更新范围属性。不幸的是,我找不到一个"干净"的方法来做这件事。我现在唯一能做到这一点的方法是在处理程序中显式调用$apply()。我知道,这是一种糟糕的做法,但它也阻止我将此代码与本机角度指令共享,例如与ng-click="myDOMEventHandler()"共享(因为它会触发$apply already in progress异常。

有没有一种方法可以将DOM事件添加到指令元素中,从而获取对作用域的更改,但不必调用$apply()

这里有一个简单的例子来说明我的意思。您也可以编辑此Plunker)。

angular.module('myApp', [])
.directive('myDirective', function ($compile) {
  return {
    link: function (scope, element) {
      scope.keystrokes = 0;
      var report = angular.element('<div ng-click="increment()">keystrokes: {{keystrokes}}</div>');
      element.after(report);
      $compile(report)(scope);
      scope.increment = function () {
        scope.keystrokes += 1;
        scope.$apply();
      };
      element.on('keyup', scope.increment);
    }
  };
});

如果在输入中输入一些文本,计数器会递增。如果单击该按钮,计数器也会递增,但如果会引发$apply already in progress异常。

如果删除scope.$apply(),那么异常就会消失,作用域属性也会发生更改,但这些更改永远不会显示。

您不必使用scope$在scope.inrement函数内应用,但应该使用

$applyelement.on('keyup'...))内,当您绑定角度范围外的事件时

angular.module('myApp', [])
.directive('myDirective', function ($compile) {
  return {
    link: function (scope, element) {
      scope.keystrokes = 0;
      var report = angular.element('<div>keystrokes and clicks: {{keystrokes}} <button ng-click="increment()">Or click me</button></div>');
      element.after(report);
      $compile(report)(scope);
      scope.increment = function () {
        scope.keystrokes += 1;
      
      };
      
      element.on('keyup', function(){
        
        scope.$apply(function(){
          
          scope.increment();
          
        });
        
        
      });
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
  <input my-directive="" />
</body>