Angular 指令 - 何时以及如何使用 compile、controller、pre-link 和 post-link [英] Angular directives - when and how to use compile, controller, pre-link and post-link
问题描述
在编写 Angular 指令时,可以使用以下任何函数来操作声明指令的元素的 DOM 行为、内容和外观:
- 编译
- 控制器
- 预链接
- 发布链接
对于应该使用哪个函数似乎有些困惑.这个问题包括:
指令基础
功能性质,该做什么和不该做什么
相关问题:
- 指令:链接 vs 编译 vs 控制器.
- 定义 angular.js 指令时控制器"、链接"和编译"函数之间的区别.莉>
- angularjs 中的编译和链接函数有什么区别.
- AngularJS 指令中预编译和后编译元素之间的区别?.
- Angular JS 指令 - 模板、编译或链接?.
- Angular js 指令中的后链接与前链接.
指令函数的执行顺序是什么?
对于单个指令
基于以下 plunk,考虑以下 HTML 标记:
<div log='some-div'></div>
使用以下指令声明:
myApp.directive('log', function() {返回 {控制器:函数($scope,$element,$attrs,$transclude){console.log( $attrs.log + ' (controller)' );},编译:函数编译(tElement,tAttributes){console.log( tAttributes.log + ' (compile)' );返回 {前:函数preLink(范围,元素,属性){console.log( attributes.log + ' (pre-link)' );},帖子:函数postLink(范围,元素,属性){console.log( attributes.log + ' (post-link)' );}};}};});
控制台输出将是:
some-div (编译)some-div(控制器)some-div(预链接)some-div(后链接)
我们可以看到先执行compile
,然后是controller
,然后是pre-link
,最后是post-link代码>.
对于嵌套指令
<块引用>注意:以下内容不适用于在其链接函数中呈现其子项的指令.相当多的 Angular 指令都这样做(如 ngIf、ngRepeat 或任何带有 transclude
的指令).这些指令将在其子指令 compile
被调用之前,先调用它们的 link
函数.
原始的 HTML 标记通常由嵌套元素组成,每个元素都有自己的指令.就像在以下标记中一样(参见 plunk):
<div log='parent'><div log='..first-child'></div><div log='..second-child'></div>
控制台输出如下所示:
//编译阶段父(编译)..第一个孩子(编译)..second-child(编译)//链接阶段父(控制者)父级(预链接)..first-child(控制器)..第一个孩子(预链接)..第一个孩子(后链接)..second-child(控制器)..second-child(预链接)..second-child(后链接)家长(后链接)
我们可以在这里区分两个阶段 - compile 阶段和 link 阶段.
编译阶段
当加载 DOM 时,Angular 开始编译阶段,它自顶向下遍历标记,并在所有指令上调用 compile
.从图形上看,我们可以这样表达:
可能需要提及的是,在此阶段,compile 函数获取的模板是源模板(而不是实例模板).
链接阶段
DOM 实例通常只是将源模板渲染到 DOM 的结果,但它们可能由 ng-repeat
创建,或动态引入.
每当带有指令的元素的新实例呈现到 DOM 时,链接阶段就会开始.
在这个阶段,Angular 调用controller
、pre-link
、迭代子节点,并在所有指令上调用post-link
,就像这样:
When writing an Angular directive, one can use any of the following functions to manipulate the DOM behaviour, contents and look of the element on which the directive is declared:
- compile
- controller
- pre-link
- post-link
There seem to be some confusion as for which function should one use. This question covers:
Directive basics
- How to declare the various functions?
- What is the difference between a source template and an instance template?
- In which order the directive functions are executed?
- What else happens between these function calls?
Function nature, do's and dont's
Related questions:
- Directive: link vs compile vs controller.
- Difference between the 'controller', 'link' and 'compile' functions when defining an angular.js directive.
- What is the difference between compile and link function in angularjs.
- Difference between the pre-compile and post-compile element in AngularJS directives?.
- Angular JS Directive - Template, compile or link?.
- post link vs pre link in Angular js directives.
In which order the directive functions are executed?
For a single directive
Based on the following plunk, consider the following HTML markup:
<body>
<div log='some-div'></div>
</body>
With the following directive declaration:
myApp.directive('log', function() {
return {
controller: function( $scope, $element, $attrs, $transclude ) {
console.log( $attrs.log + ' (controller)' );
},
compile: function compile( tElement, tAttributes ) {
console.log( tAttributes.log + ' (compile)' );
return {
pre: function preLink( scope, element, attributes ) {
console.log( attributes.log + ' (pre-link)' );
},
post: function postLink( scope, element, attributes ) {
console.log( attributes.log + ' (post-link)' );
}
};
}
};
});
The console output will be:
some-div (compile)
some-div (controller)
some-div (pre-link)
some-div (post-link)
We can see that compile
is executed first, then controller
, then pre-link
and last is post-link
.
For nested directives
Note: The following does not apply to directives that render their children in their link function. Quite a few Angular directives do so (like ngIf, ngRepeat, or any directive with
transclude
). These directives will natively have theirlink
function called before their child directivescompile
is called.
The original HTML markup is often made of nested elements, each with its own directive. Like in the following markup (see plunk):
<body>
<div log='parent'>
<div log='..first-child'></div>
<div log='..second-child'></div>
</div>
</body>
The console output will look like this:
// The compile phase
parent (compile)
..first-child (compile)
..second-child (compile)
// The link phase
parent (controller)
parent (pre-link)
..first-child (controller)
..first-child (pre-link)
..first-child (post-link)
..second-child (controller)
..second-child (pre-link)
..second-child (post-link)
parent (post-link)
We can distinguish two phases here - the compile phase and the link phase.
The compile phase
When the DOM is loaded Angular starts the compile phase, where it traverses the markup top-down, and calls compile
on all directives. Graphically, we could express it like so:
It is perhaps important to mention that at this stage, the templates the compile function gets are the source templates (not instance template).
The link phase
DOM instances are often simply the result of a source template being rendered to the DOM, but they may be created by ng-repeat
, or introduced on the fly.
Whenever a new instance of an element with a directive is rendered to the DOM, the link phase starts.
In this phase, Angular calls controller
, pre-link
, iterates children, and call post-link
on all directives, like so:
这篇关于Angular 指令 - 何时以及如何使用 compile、controller、pre-link 和 post-link的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!