事件侦听器的指令优先级

Directive priority with event listener

我有一个带有 2 个指令的输入元素:
-direc(优先级 1)
-指令(优先级 0)

即使 direc 应该先执行,directive 也会先执行。
为什么?

这里有一个片段来展示正在发生的事情

angular.module('app', [])


.directive('direc', function(){
  
  return {
    priority : 1,
    link : function(scope, element){
      
      element.on('click', function(){
          alert('direc');
      });
    
    }
  };  

})

.directive('directive', function(){
  
  return {
    priority : 0,
    link : function(scope, element){
      
      element.on('click', function(){
          alert('directive');
      });
    
    }
  };  

});
<div ng-app="app">

   <input type="text" direc directive/>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

根据文档:

When there are multiple directives defined on a single DOM element, sometimes it is necessary to specify the order in which the directives are applied. The priority is used to sort the directives before their compile functions get called. Priority is defined as a number. Directives with greater numerical priority are compiled first. Pre-link functions are also run in priority order, but post-link functions are run in reverse order. The order of directives with the same priority is undefined. The default priority is 0.

我认为您混淆了优先级的功能,因为它与先调用哪个指令的事件侦听器无关,而是先调用哪个指令的 运行 它们的 link 函数。

如果在执行 link 函数时对元素进行更改,您可以看到不同之处:

angular.module('app', [])
.directive('direc', function(){

  return {
    priority : 1,
    link : function(scope, element){
      element.html('direc with priority 1');

      element.on('click', function(){
        alert('direc');
      });

    }
  };  

})

.directive('directive', function(){

  return {
    priority : 0,
    link : function(scope, element){
      element.html('directive with priority 0');

      element.on('click', function(){
        alert('directive');
      });

    }
  };  

});

具有最低优先级的元素是 运行 的最后一个元素,因此结果 HTML 是 "direc with priority 1"

这是一个有效的插件:http://plnkr.co/edit/VKqiMQDyMFsFguuRp7Ko?p=preview

基本上当指令进入图片时发生的事情,angular 运行 指令 compile 首先发挥作用。

compile 中,您可以控制原始 DOM / 普通 DOM,在 compile 函数中,您将没有作用域。编译函数负责返回preLinkpostLink函数。其中 preLink 首先被调用

preLink 函数中,您可以使用范围 DOM,在 preLink 之后,它会渲染内部元素或其他指令。在遍历 DOM 的每个元素后,它会触发 postLink 函数。其中纯粹编译 DOM 范围。这就是为什么 directive 的事件首先被注册,因为它具有最低的优先级并具有其功能 postLink.

Plunkr for Understanding Flow(看控制台更清楚)

您应该在 preLink 函数中注册这些事件,以便在指令函数编译执行后注册事件。

代码

angular.module('app', [])
.directive('direc', function() {
  return {
    priority: 1,
    compile: function(element, attributes) {
      console.log("Compiled direc")
      return {
        pre: function(scope, element, attrs) {
          console.log("Prelink for direc firective generated");
          element.on('click', function() {
            alert('direc');
          });
        },
        post: function(scope, element, attrs) {
          console.log("Called After direc DOM linked with scope")
        }
      }
    },
  }
})
.directive('directive', function() {
  return {
    priority: 0,
    compile: function(element, attributes) {
      console.log("Compiled direc")
      return {
        pre: function(scope, element, attrs) {
          console.log("Prelink for direc firective generated");
          element.on('click', function() {
            alert('directive');
          });
        },
        post: function(scope, element, attrs) {
          console.log("Called After directive DOM linked with scope")
        }
      }
    },
  };
});

Working Plunkr