【问题标题】:Angular Parent/Child Directive's order of executionAngular 父/子指令的执行顺序
【发布时间】:2015-02-23 08:08:27
【问题描述】:

根据 angulars 文档,“父”的发布链接功能将仅在子指令的发布链接功能执行后执行。

但是,如果是以下代码,为什么我需要触发“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');
  };
});

我无法掌握指令执行顺序的概念。我心中对上述指令的疑问总是让我感到困惑。请帮助我理解这一点。先谢谢了!!!

【问题讨论】:

标签: angularjs angularjs-directive


【解决方案1】:

这会有所不同,您可以在plnkr 中运行一个简单的测试。这是api reference

在指令中你有一个compile 函数。你可以从它返回一个函数,它是一个对象并且有两个属性,prepostlink 属性也是如此,但是如果 compile 函数存在并且链接被忽略并且链接应该只是一个包含 prepost 的对象,则会执行它。

compile 函数处理模板 DOM 的转换。由于大部分指令不做模板转换,所以不经常使用

链接

仅当未定义编译属性时才使用此属性。

.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");
    }
}

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

您会注意到,首先所有的 pre 编译都在树中完成,然后在返回的路上它执行所有 post 编译。

链接

预链接功能

在链接子元素之前执行。做 DOM 不安全 转换,因为编译器链接函数将无法定位 链接的正确元素。

后链接功能

子元素链接后执行。

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

在后链接功能中进行 DOM 转换是安全的 不等待其异步模板的元素 解决了。​​


您不必定义prepost。事实上,您可以通过以下方式定义 post 函数:

compile: function (scope, elem) {},
link: function (scope, elem) {}

所以基本上,没有明确定义 prepost 假定它们是 post


ng-repeat 而言,它将视图属性添加到可用于确定事物的指令范围内。如果您阅读this,您会发现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>

这是最适合你的场景的。

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

$even: true
$first: true
$id: 3
$index: 0
$last: false
$middle: false
$odd: false

plnkr

由于文档中的以下声明,ng-repeat 可能会按预期以不同方式执行 prepost

此指令以优先级 1000 执行。

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

如果您更改优先级,则会根据prepost 编译以及可能链接修改执行顺序。我不确定还有什么受此影响。

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

【讨论】:

  • 您好,感谢您的回复!!!我已经检查了你的 plunkr。它按预期工作正常。尝试将“ng-repeat”添加到子元素并查看行为。父级的“Pre”和“Post”都将首先执行。而预期的行为应如下所述:1. 父母的预链接 2. 孩子的预链接 3. 孩子的帖子链接 4. 父母的帖子链接 请评论此行为,这是我的实际问题。
  • 我仍然得到相同的顺序,它会 pre 父级,然后是子级 - 然后是 post 子级,然后是父级。由于ng-repeat,此行为将重复。这是我所期望的。 @mkdudeja
  • @mkdudeja 我只是更新了 plnkr 以包括指令是父还是子。再次检查帖子顶部的链接
  • 请查看以下 plunkr 示例:plnkr.co/edit/gY4DtTlbIIXN9c4mjJnA?p=preview 查看控制台的日志
  • 所以据我所知,在 ng-repeat 开始之前是 prepost。我不知道为什么,但是如果您在底部看到我修改后的答案,您可以访问ng-repeat 信息。 plnkr
猜你喜欢
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 2021-11-03
相关资源
最近更新 更多