adding more directives是我试图建立的一个元素.

如果我try 添加这些属性,然后使用$compile,显然会生成一个无限循环,因此我正在判断是否已经添加了所需的属性:

angular.module('app')
  .directive('superDirective', function ($compile, $injector) {
    return {
      restrict: 'A',
      replace: true,
      link: function compile(scope, element, attrs) {
        if (element.attr('datepicker')) { // check
          return;
        }
        element.attr('datepicker', 'someValue');
        element.attr('datepicker-language', 'en');
        // some more
        $compile(element)(scope);
      }
    };
  });

当然,如果我不输入元素,属性会被设置,但指令不会被 bootstrap .

这种方法是正确的还是我做错了?有没有更好的方法来实现同样的行为?

UDPATE:考虑到$compile是实现这一点的唯一方法,有没有办法跳过第一次编译过程(元素可能包含几个子元素)?也许设定terminal:true

UPDATE 2:我try 将指令放入select元素,不出所料,编译运行了两次,这意味着预期option的数量是预期的两倍.

推荐答案

如果在单个DOM元素上有多个指令,并且 它们被应用的顺序,您可以使用priority属性来排序它们的 申请.数字越高,就会先运行.如果未指定优先级,则默认优先级为0.

EDIT:经过讨论,下面是完整的工作解决方案.关键是remove the attribute:element.removeAttr("common-things");,还有element.removeAttr("data-common-things");(如果用户在html中指定data-common-things)

angular.module('app')
  .directive('commonThings', function ($compile) {
    return {
      restrict: 'A',
      replace: false, 
      terminal: true, //this setting is important, see explanation below
      priority: 1000, //this setting is important, see explanation below
      compile: function compile(element, attrs) {
        element.attr('tooltip', '{{dt()}}');
        element.attr('tooltip-placement', 'bottom');
        element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
        element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html

        return {
          pre: function preLink(scope, iElement, iAttrs, controller) {  },
          post: function postLink(scope, iElement, iAttrs, controller) {  
            $compile(iElement)(scope);
          }
        };
      }
    };
  });

工作plunker的价格为:http://plnkr.co/edit/Q13bUt?p=preview

或者:

angular.module('app')
  .directive('commonThings', function ($compile) {
    return {
      restrict: 'A',
      replace: false,
      terminal: true,
      priority: 1000,
      link: function link(scope,element, attrs) {
        element.attr('tooltip', '{{dt()}}');
        element.attr('tooltip-placement', 'bottom');
        element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
        element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html

        $compile(element)(scope);
      }
    };
  });

DEMO

Explanation why we have to set 100 and 101 (a high number):

当DOM准备就绪时,angular将遍历DOM以识别所有已注册的指令,并基于priority if these directives are on the same element逐个编译这些指令.我们将自定义指令的优先级设置为一个较高的数字,以确保它将被编译为first,对于terminal: true,其他指令将在编译该指令后被编译为skipped.

当我们的自定义指令被编译时,它将通过添加指令和删除自身来修改元素,并使用$compile service将其设置为compile all the directives (including those that were skipped).

If we don't set terminal:true and priority: 1000, there is a chance that some directives are compiled before our custom directive. And when our custom directive uses $compile to compile the element => compile again the already compiled directives. This will cause unpredictable behavior especially if the directives compiled before our custom directive have already transformed the DOM.

有关优先级和终端的更多信息,请查看How to understand the `terminal` of directive?

同样修改模板的指令示例为ng-repeat(优先级=ng-repeat0),编译ng-repeat时为ng-repeat make copies of the template element before other directives get applied.

感谢@Izhaki的 comments ,这里是ngRepeat源代码的参考:https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js

Javascript相关问答推荐

如何从JavaScript中的公共方法调用私有方法?

为什么我的第二个OnClick Isloading值在TEK查询Mutations 查询中不起作用?

无法将nPM simplex-noise包导入在JS项目中工作

有什么(最佳)方法可以从模块中获取脚本模块的多姆元素吗?

如何访问Json返回的ASP.NET Core 6中的导航图像属性

Klaro与Angular的集成

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

在页面上滚动 timeshift 动垂直滚动条

类型脚本中只有字符串或数字键而不是符号键的对象

InDesign—创建一个独立的窗口,在文档中进行更正时保持打开状态

使用i18next在React中不重新加载翻译动态数据的问题

使用useEffect,axios和useParams进行react测试

在open shadow—root中匹配时,使用jQuery删除一个封闭的div类

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

禁用.js文件扩展名并从目录导入隐式根index.js时,找不到NodeJS导入模块

在开发期间,Web浏览器如何运行&qot;.jsx&qot;文件?

自定义确认组件未在vue.js的v菜单内打开

为什么云存储中的文件不能公开使用?

是否可以将异步调用与useState(UnctionName)一起使用

使用可配置项目创建网格