我的指令在 ngRepeat 和 ngInclude 之前执行,尽管默认优先级为 0

My directive is executed before ngRepeat and ngInclude, despite of default priority 0

我的自定义指令编译函数在 ngRepeat (priority=1000) 和 ngInclude (priority=400) 之前执行,尽管默认优先级是 0,所以它应该在之后执行。

片段显示缺少 myDir 指令附加的内容,仅显示 ngInclude 模板中包含的内容:

angular.module("app", [])
.run(function($templateCache) {
  $templateCache.put('test.html', '<p>Content included by ngInclude</p><span>Number {{$index}}</span>');
})
.directive("myDir", function() {
    return {
        compile: function(elm){
            elm.append('<span>apended by directive myDir, 1+1={{1+1}}</span>');
            return function link(){};
        }
    };
})
.controller("myApp", function($scope){
    $scope.items = [1,2,3];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myApp">
    <div ng-repeat="item in items" my-dir="" ng-include="'test.html'"><p>First content</p></div>
</div>

我在 jsfiddle 中有相同的代码:jsfiddle-link 在那里它显示了预期的行为。显示指令的附加文本。 因为在 ngRepeat 和 ngInclude 编译函数之后附加了最低优先级的文本。

示例之间的差异仅在 angular 版本中。此处截图在 v1.2.23 上运行(与我的项目 运行 v1.3.0 中的行为相同)并且 jsfiddle 在 v1.2.1

上运行

欢迎任何建议,提前致谢;)

PS: 在jsfiddle例子中,视图中缺少“<span>Number {{$index}}</span>”部分,告诉我原因的人加分。

他们似乎添加了 ngIncludeFillContentDirective 指令(也在 ngInclude 名称下注册),它取代了整个 html:

var ngIncludeFillContentDirective = ['$compile',
  function($compile) {
    return {
      restrict: 'ECA',
      priority: -400,
      require: 'ngInclude',
      link: function(scope, $element, $attr, ctrl) {
        if (/SVG/.test($element[0].toString())) {
          // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not
          // support innerHTML, so detect this here and try to generate the contents
          // specially.
          $element.empty();
          $compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope,
              function namespaceAdaptedClone(clone) {
            $element.append(clone);
          }, {futureParentElement: $element});
          return;
        }

        $element.html(ctrl.template);
        $compile($element.contents())(scope);
      }
    };
  }];

它以优先级 -400 运行,因此您的指令在 ngRepeat 和 ngInclude 之后但在此之前执行。

我不确定,但我认为问题在于 ngInclude 是终端。

ng documentation:

terminal

If set to true then the current priority will be the last set of directives which will execute (any directives at the current priority will still execute as the order of execution on same priority is undefined). Note that expressions and other directives used in the directive's template will also be excluded from execution.

这是我的解决方法(DOM 在 link fn 中操作而不是编译 fn):

angular.module("app", [])
.run(function($templateCache) {
  $templateCache.put('test.html', '<p>Content included by ngInclude</p><span>Number {{$index}}</span>');
})
.directive("myDir", function($compile) {
    return {
        link: function(scope, elm){
            elm.append($compile('<br><span>apended by directive myDir, 1+1={{1+1}}</span>')(scope));
        }
    };
})
.controller("myApp", function($scope){
    $scope.items = [1,2,3];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myApp">
    <div ng-repeat="item in items" my-dir="" ng-include="'test.html'"><p>First content</p></div>
</div>