有人能简单解释一下吗?
文档看起来有点迟钝。我没有领会到什么时候该用一种而不是另一种的本质和大局。一个对比这两者的例子会很棒。
有人能简单解释一下吗?
文档看起来有点迟钝。我没有领会到什么时候该用一种而不是另一种的本质和大局。一个对比这两者的例子会很棒。
当前回答
从文档中可以看出:
Compiler Compiler is an angular service which traverses the DOM looking for attributes. The compilation process happens into two phases. Compile: traverse the DOM and collect all of the directives. The result is a linking function. Link: combine the directives with a scope and produce a live view. Any changes in the scope model are reflected in the view, and any user interactions with the view are reflected in the scope model. Making the scope model a single source of truth. Some directives such ng-repeat clone DOM elements once for each item in collection. Having a compile and link phase improves performance since the cloned template only needs to be compiled once, and then linked once for each clone instance.
所以至少在某些情况下,这两个阶段作为优化是分开存在的。
从@UmurKontacı:
如果要进行DOM转换,则应该进行compile。如果你想添加一些行为变化的特性,它应该在link中。
其他回答
从文档中可以看出:
Compiler Compiler is an angular service which traverses the DOM looking for attributes. The compilation process happens into two phases. Compile: traverse the DOM and collect all of the directives. The result is a linking function. Link: combine the directives with a scope and produce a live view. Any changes in the scope model are reflected in the view, and any user interactions with the view are reflected in the scope model. Making the scope model a single source of truth. Some directives such ng-repeat clone DOM elements once for each item in collection. Having a compile and link phase improves performance since the cloned template only needs to be compiled once, and then linked once for each clone instance.
所以至少在某些情况下,这两个阶段作为优化是分开存在的。
从@UmurKontacı:
如果要进行DOM转换,则应该进行compile。如果你想添加一些行为变化的特性,它应该在link中。
这个问题太老了,我想做一个简短的总结,这可能会有所帮助:
编译为所有指令实例调用一次 编译的主要目的是返回/创建链接(可能是前/后)函数/对象。你也可以init指令实例间共享的东西。 在我看来,“链接”是这个功能的一个令人困惑的名字。我更喜欢“预渲染”。 link为每个指令实例调用,它的目的是准备在DOM中呈现指令。
compile function - use for template DOM manipulation (i.e., manipulation of tElement = template element), hence manipulations that apply to all DOM clones of the template associated with the directive. link function - use for registering DOM listeners (i.e., $watch expressions on the instance scope) as well as instance DOM manipulation (i.e., manipulation of iElement = individual instance element). It is executed after the template has been cloned. E.g., inside an <li ng-repeat...>, the link function is executed after the <li> template (tElement) has been cloned (into an iElement) for that particular <li> element. A $watch() allows a directive to be notified of instance scope property changes (an instance scope is associated with each instance), which allows the directive to render an updated instance value to the DOM -- by copying content from the instance scope into the DOM.
注意,DOM转换可以在compile函数和/或link函数中完成。
大多数指令只需要一个链接函数,因为大多数指令只处理特定的DOM元素实例(及其实例作用域)。
One way to help determine which to use: consider that the compile function does not receive a scope argument. (I'm purposely ignoring the transclude linking function argument, which receives a transcluded scope -- this is rarely used.) So the compile function can't do anything you would want to do that requires an (instance) scope -- you can't $watch any model/instance scope properties, you can't manipulate the DOM using instance scope information, you can't call functions defined on the instance scope, etc.
但是,compile函数(像link函数一样)可以访问属性。因此,如果DOM操作不需要实例作用域,则可以使用compile函数。由于这些原因,这里有一个只使用compile函数的指令示例。它检查属性,但是不需要实例作用域来完成它的工作。
下面是一个同样只使用compile函数的指令示例。该指令只需要转换模板DOM,因此可以使用compile函数。
另一种帮助确定使用哪个的方法:如果在链接函数中不使用"element"参数,那么可能不需要链接函数。
因为大多数指令都有一个链接函数,所以我不打算提供任何示例——它们应该很容易找到。
注意,如果你需要一个编译函数和一个链接函数(或前和后链接函数),编译函数必须返回一个或多个链接函数,因为如果定义了'compile'属性,'link'属性将被忽略。
另请参阅
在定义指令时,'controller', 'link'和'compile'函数之间的区别 Dave Smith关于指令的精彩ng-conf 2104演讲(链接到视频中关于编译和链接的部分)
这是Misko关于指令的演讲。http://youtu.be/WqmeI5fZcho?t=16m23s
Think of the compiler function as the thing that works on a template and the thing that is allowed to change the template itself by, for example, adding a class to it or anything like that. But it's the linking function that actually does the work of binding the two together because the linking function has access to the scope and it's the linking function that executes once for each instantiation of the particular template. So the only kind of things you can placed inside of the compile functions are things that are common across all of the instances.
有点晚了。但是,为了方便将来的读者:
我偶然看到下面这个视频,它以一种非常棒的方式解释了Angular JS中的编译和链接:
https://www.youtube.com/watch?v=bjFqSyddCeA
复制/输入这里的所有内容不太令人愉快。我从视频中截取了几个截图,解释了编译和链接阶段的每个阶段:
第二张截图有点让人困惑。但是,如果我们按照步长编号,就很简单了。
第一个循环:首先在所有指令上执行“Compile”。 第二个循环:执行“Controller”和“Pre-Link”(只是一个接一个) 第三个循环:“Post-Link”以相反的顺序执行(从最里面开始)
下面是代码,它演示了上面的内容:
var app = angular.module('app', []); app.controller('msg', ['$scope', function($scope){ }]); app.directive('message', function($interpolate){ return{ compile: function(tElement, tAttributes){ console.log(tAttributes.text + " -In compile.."); return { pre: function(scope, iElement, iAttributes, controller){ console.log(iAttributes.text + " -In pre.."); }, post: function(scope, iElement, iAttributes, controller){ console.log(iAttributes.text + " -In Post.."); } } }, controller: function($scope, $element, $attrs){ console.log($attrs.text + " -In controller.."); }, } });
<body ng-app="app">
<div ng-controller="msg">
<div message text="first">
<div message text="..second">
<div message text="....third">
</div>
</div>
</div>
</div>
更新:
该视频的第二部分可以在这里找到:https://www.youtube.com/watch?v=1M3LZ1cu7rw,该视频以一个简单的例子解释了如何在Angular JS的编译和链接过程中修改DOM和处理事件。