Angular Parent/Child Directive的执行顺序

Man*_*mar 3 angularjs angularjs-directive

根据angulars文档,只有在执行了子指令的post link函数后,才会执行"Parent"的Post link功能.

但是,在以下代码的情况下,为什么我需要触发"emit"事件来通知ng-repeat已经完成.理想情况下,它应该自动运行而不需要发出事件.

<div ng-controller="Ctrl" my-main-directive>
  <div ng-repeat="thing in things" my-repeat-directive>
    thing {{thing}}
  </div>
</div>

angular.module('myApp', [])
.directive('myRepeatDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('color','blue');
    if (scope.$last){
      window.alert("im the last!");
    }
  };
})
.directive('myMainDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('border','5px solid red');
  };
});
Run Code Online (Sandbox Code Playgroud)

我无法掌握指令执行顺序的概念.对于像上面提到的指令一样,我心中的疑问总让我感到困惑.请帮我理解这个.提前致谢!!!

Cal*_*ton 5

这是不同的,你可以在plnkr中运行一个简单的测试.这是api参考

在指令中你有一个compile功能.您可以从它返回一个作为对象的函数,并具有两个属性pre,post.然后link属性也一样,但是compile如果它存在并且忽略链接并且链接应该只是包含pre和的对象,则执行该函数post.

编译函数处理转换模板DOM.由于大多数指令不进行模板转换,因此不经常使用

链接

仅在未定义compile属性时才使用此属性.

.directive('myDir', myDir);

function myDir() {
    var directive = {
         compile: compile,
         link: {
            pre: preLink,
            post: postLink
         }
    };

    return directive;

    function compile() {
        return {
           pre: preCompile,
           post: postCompile
        }
    }

    function preCompile(scope, elem) {
        console.log("Pre Compile");
    }

    function postCompile(scope, elem) {
        console.log("Post Compile");
    }

    function preLink(scope, elem) {
        console.log("Pre Link");
    }

    function postLink(scope, elem) {
        console.log("Post Link");
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您运行此命令,使用另一个具有相同的指令,并且您修改了控制台日志,以便了解发布的内容,您很快就会看到它的作用!

你注意到的是,首先所有的pre编译都进入树中,然后在回来的路上执行所有的post编译.

链接

预连接功能

在子元素链接之前执行.由于编译器链接功能无法找到正确的链接元素,因此进行DOM转换是不安全的.

后连接功能

链接子元素后执行.

请注意,包含templateUrl指令的子元素将不会被编译和链接,因为它们正在等待其模板异步加载,并且它们自己的编译和链接已暂停,直到发生这种情况.

在不等待解析异步模板的元素的后连接函数中进行DOM转换是安全的.


您不必定义prepost.实际上,您可以post通过执行以下操作来定义函数:

compile: function (scope, elem) {},
link: function (scope, elem) {}
Run Code Online (Sandbox Code Playgroud)

所以基本上,没有明确定义a pre或者post假定它们是post.


ng-repeat它而言,它将视图属性添加到指令范围,您可以使用它来确定事物.如果你给这个一读,你会发现有相当多的,你可以用做ng-repeat.

<header ng-repeat-start="item in items">
  Header {{ item }}
</header>
<div class="body">
  Body {{ item }}
</div>
<footer ng-repeat-end>
  Footer {{ item }}
</footer>
Run Code Online (Sandbox Code Playgroud)

这最适用于您的方案.

以下是您可以访问的范围的一些属性:

$even: true
$first: true
$id: 3
$index: 0
$last: false
$middle: false
$odd: false
Run Code Online (Sandbox Code Playgroud)

plnkr

ng-repeat可以执行prepost预期,因为从文档这一说法的不同:

该指令在优先级1000执行.

这是一个plnkr,显示如果更改优先级会发生什么.

如果您更改优先级,则会出现,这将根据prepost编译以及链接修改执行顺序.我不确定还有什么会受到影响.

我希望这对您有所帮助,如果需要,请评论以获得更多帮助!