简体   繁体   English

角度维护指令列表

[英]Angular Maintain List of Directives in Order

I want to maintain a list of directives on a page in the order they appear in the dom. 我想按它们在dom中出现的顺序在页面上维护指令列表。 I know directives are created (link function called) in order, and I can append them to an array when being linked, but how do I handle dynamic pages (ajax, ngRepeats, etc..). 我知道指令是按顺序创建的(称为链接函数),可以在链接时将它们附加到数组中,但是如何处理动态页面(ajax,ngRepeats等)。 Currently every time I need to use the array I broadcast an event to get the directives in order. 当前,每次需要使用数组时,我都会广播事件以按顺序获取指令。

gatherDirectives: ->
  all = []
  $rootScope.$broadcast 'roleCall', (dir) -> all.push dir
  all

But I'd rather have directives register and unregister when being created and removed to be more efficient. 但是我宁愿让指令在创建和删除时进行注册和注销,以提高效率。 Something like what is discussed on AngularJS directive - setting order for multiple directive elements (not priority for directives, but priority for the elements) , but that can handle dynamically added/removed directives. 类似于在AngularJS指令上讨论的内容-设置多个指令元素的顺序(不是指令的优先级,而是元素的优先级) ,但是可以处理动态添加/删除的指令。 How can this be done without gathering the directives each time? 如何在不每次都收集指令的情况下完成此操作?

"I want to maintain a list of directives on a page in the order they appear in the dom." “我想按照页面在dom中出现的顺序维护页面上的指令列表。”

Can these methods help you? 这些方法可以帮助您吗?

Priority 优先

AngularJS finds all directives associated with an element and processes it. AngularJS查找与元素关联的所有指令并对其进行处理。 This option tells angular to sort directives by priority so a directive having higher priority will be compiled/linked before others. 此选项告诉角度排序指令按优先级排序,因此优先级较高的指令将先于其他指令被编译/链接。 The reason for having this option is that we can perform conditional check on the output of the previous directive compiled. 使用此选项的原因是我们可以对编译后的前一条指令的输出执行条件检查。 In the below example, I want to add btn-primary class only if a div has btn class on it. 在下面的示例中,仅当div上具有btn类时,我才想添加btn-primary类。

<div style='padding:100px;'>
  <div primary btn>Random text</div>
</div>

Please note that the default priority if not set will be zero. 请注意,默认优先级(如果未设置)将为零。 In this example, btn directive will be executed before primary. 在此示例中,btn指令将在primary之前执行。 Play with the demo! 玩演示!

App.directive('btn', function($timeout) {
  return {
    restrict: 'A',
    priority: 1,
    link: function(scope, element, attrs) {
      element.addClass('btn');
    }
  };
});

App.directive('primary', function($http) {
  return {
    restrict: 'A',
    priority: 0,
    link: function(scope, element, attrs) {
      if (element.hasClass('btn')) {
        element.addClass('btn-primary');
      }
    }
  };
});

Terminal 终奌站

As per the official documentation, If set to true then the current priority will be the last set of directives which will execute on an element. 根据官方文档,如果设置为true,则当前优先级将是将在元素上执行的最后一组指令。 It holds true unless you use custom directives in conjunction with built-in directives having priority set on them such as ngRepeat, ngSwitch, etc. Instead all custom directives having a priority greater than or equal the current priority will not be executed in this case. 除非您将自定义指令与设置了优先级的内置指令(例如ngRepeat,ngSwitch等)结合使用,否则它是正确的。在这种情况下,将不会执行优先级大于或等于当前优先级的所有自定义指令。 In the below example, first has a higher priority than second – which has terminal set to true. 在下面的示例中,第一个具有比第二个更高的优先级–第二个将终端设置为true。 And if you set the lower priority to first – It will not be executed at all. 而且,如果将较低的优先级设置为“第一”,则将完全不执行该优先级。 But in case of no-entry directive, it will not be executed even though it has a higher priority than ng-repeat. 但是在不进入指令的情况下,即使它的优先级高于ng-repeat,也不会执行。 Is it a bug? 是虫子吗? Is it because of transclusion used in ng-repeat? 是因为ng-repeat中使用了包含法吗? Need to dig in… 需要挖掘...

<div first second></div>

<ul>
    <li ng-repeat="item in ['one', 'two', 'three']" no-entry>{{item}} </li>
</ul>



App.directive('first', function() {
  return {
    restrict: 'A',
    priority: 3,
    link: function(scope, element, attrs) {
      element.addClass('btn btn-success').append('First: Executed, ');
    }        
  };
});

App.directive('second', function() {
  return {
    restrict: 'A',
    priority: 2,
    terminal: true,
    link: function(scope, element, attrs) {
      element.addClass('btn btn-success').append('Second: Executed ');
    }        
  };
});

App.directive('noEntry', function() {
  return {
    restrict: 'A',
    priority: 1001,
    link: function(scope, element, attrs) {
      element.append('No Entry: Executed ');
    }        
  };
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM