Javascript 定义指令时“控制器”、“链接”和“编译”函数之间的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12546945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 10:40:31  来源:igfitidea点击:

Difference between the 'controller', 'link' and 'compile' functions when defining a directive

javascriptangularjsweb-applicationsjavascript-framework

提问by user1558259

Some places seem to use the controller function for directive logic and others use link. The tabs example on the angular homepage uses controller for one and link for another directive. What is the difference between the two?

有些地方似乎将控制器功能用于指令逻辑,而其他地方则使用链接。angular 主页上的选项卡示例使用控制器作为一个指令并使用链接作为另一个指令。两者有什么区别?

回答by Mark Rajcok

I'm going to expand your question a bit and also include the compile function.

我将扩展您的问题并包括编译功能。

  • compile function- use for templateDOM manipulation (i.e., manipulation of tElement = template element), hence manipulations that apply to all DOM clones of the template associated with the directive. (If you also need a link function (or pre and post link functions), and you defined a compile function, the compile function must return the link function(s) because the 'link'attribute is ignored if the 'compile'attribute is defined.)

  • link function- normally use for registering listener callbacks (i.e., $watchexpressions on the scope) as well as updating the DOM (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 $watchallows a directive to be notified of scope property changes (a scope is associated with each instance), which allows the directive to render an updated instance value to the DOM.

  • controller function- must be used when another directive needs to interact with this directive. E.g., on the AngularJS home page, the pane directive needs to add itself to the scope maintained by the tabs directive, hence the tabs directive needs to define a controller method (think API) that the pane directive can access/call.

    For a more in-depth explanation of the tabs and pane directives, and why the tabs directive creates a function on its controller using this(rather than on $scope), please see 'this' vs $scope in AngularJS controllers.

  • compile 函数- 用于模板DOM 操作(即操作 tElement = 模板元素),因此操作适用于与指令关联的模板的所有 DOM 克隆。(如果您还需要一个链接函数(或前链接和后链接函数),并且您定义了一个编译函数,则编译函数必须返回链接函数,因为'link'如果'compile'定义了该属性,则该属性将被忽略。)

  • 链接函数- 通常用于注册侦听器回调(即$watch作用域上的表达式)以及更新 DOM(即操作 iElement = 单个实例元素)。它在模板被克隆后执行。例如,在 a 中<li ng-repeat...>,链接函数在<li>模板 (tElement) 为该特定<li>元素克隆(到 iElement)之后执行。A$watch允许指令被通知范围属性更改(范围与每个实例相关联),这允许指令将更新的实例值呈现给 DOM。

  • 控制器功能- 当另一个指令需要与该指令交互时必须使用。例如,在 AngularJS 主页上,pane 指令需要将自己添加到 tabs 指令维护的范围,因此 tabs 指令需要定义一个控制器方法(想想 API),pane 指令可以访问/调用。

    有关选项卡和窗格指令的更深入解释,以及为什么选项卡指令使用this(而不是 on $scope)在其控制器上创建函数,请参阅AngularJS 控制器中的“this”与 $scope

In general, you can put methods, $watches, etc. into either the directive's controller or link function. The controller will run first, which sometimes matters (see this fiddlewhich logs when the ctrl and link functions run with two nested directives). As Josh mentioned in a comment, you may want to put scope-manipulation functions inside a controller just for consistency with the rest of the framework.

通常,您可以将方法、$watches等放入指令的控制器或链接函数中。控制器将首先运行,这有时很重要(请参阅此小提琴,它记录 ctrl 和链接函数何时使用两个嵌套指令运行)。正如 Josh 在评论中提到的,您可能希望将范围操作功能放在控制器中,以便与框架的其余部分保持一致。

回答by Pixic

As complement to Mark's answer, the compile function does not have access to scope, but the link function does.

作为对 Mark 答案的补充, compile 函数无法访问范围,但链接函数可以。

I really recommend this video; Writing Directivesby Misko Hevery (the father of AngularJS), where he describes differences and some techniques. (Difference between compile function and link function at 14:41 mark in the video).

我真的很推荐这个视频;由 Misko Hevery(AngularJS 之父)编写的指令,在那里他描述了差异和一些技术。(视频14:41 标记处编译函数和链接函数的区别)。

回答by Rahul

  1. running code before Compilation : use controller
  2. running code after Compilation : use Link
  1. 编译前运行代码:使用控制器
  2. 编译后运行代码:使用链接

Angular convention : write business logic in controller and DOM manipulation in link.

Angular 约定:在控制器中编写业务逻辑,在链接中编写 DOM 操作。

Apart from this you can call one controller function from link function of another directive.For example you have 3 custom directives

除此之外,您可以从另一个指令的链接函数调用一个控制器函数。例如,您有 3 个自定义指令

<animal>
<panther>
<leopard></leopard>
</panther> 
</animal>

and you want to access animal from inside of "leopard" directive.

并且您想从“豹”指令内部访问动物。

http://egghead.io/lessons/angularjs-directive-communicationwill be helpful to know about inter-directive communication

http://egghead.io/lessons/angularjs-directive-communication将有助于了解指令间通信

回答by Sunil Garg

compile function-

编译功能——

  1. is called before the controller and link function.
  2. In compile function, you have the original template DOM so you can make changes on original DOM before AngularJS creates an instance of it and before a scope is created
  3. ng-repeat is perfect example - original syntax is template element, the repeated elements in HTML are instances
  4. There can be multiple element instances and only one template element
  5. Scope is not available yet
  6. Compile function can return function and object
  7. returning a (post-link) function - is equivalent to registering the linking function via the link property of the config object when the compile function is empty.
  8. returning an object with function(s) registered via pre and post properties - allows you to control when a linking function should be called during the linking phase. See info about pre-linking and post-linking functions below.
  1. 在控制器和链接函数之前调用。
  2. 在 compile 函数中,您拥有原始模板 DOM,因此您可以在 AngularJS 创建它的实例之前和创建范围之前对原始 DOM 进行更改
  3. ng-repeat 是完美的例子 - 原始语法是模板元素,HTML 中的重复元素是实例
  4. 可以有多个元素实例并且只有一个模板元素
  5. 范围尚不可用
  6. 编译函数可以返回函数和对象
  7. 返回一个(后链接)函数——相当于在编译函数为空时通过配置对象的链接属性注册链接函数。
  8. 返回具有通过 pre 和 post 属性注册的函数的对象 - 允许您控制在链接阶段何时应调用链接函数。请参阅下面有关预链接和后链接功能的信息。

syntax

句法

function compile(tElement, tAttrs, transclude) { ... }

controller

控制器

  1. called after the compile function
  2. scope is available here
  3. can be accessed by other directives (see require attribute)
  1. 在编译函数之后调用
  2. 范围在这里可用
  3. 可以被其他指令访问(见 require 属性)

pre - link

预链接

  1. The link function is responsible for registering DOM listeners as well as updating the DOM. It is executed after the template has been cloned. This is where most of the directive logic will be put.

  2. You can update the dom in the controller using angular.element but this is not recommended as the element is provided in the link function

  3. Pre-link function is used to implement logic that runs when angular js has already compiled the child elements but before any of the child element's post link have been called

  1. link 函数负责注册 DOM 监听器以及更新 DOM。它在模板被克隆后执行。这是大多数指令逻辑将被放置的地方。

  2. 您可以使用 angular.element 更新控制器中的 dom,但不建议这样做,因为链接功能中提供了该元素

  3. Pre-link 函数用于实现在 angular js 已经编译了子元素但在调用任何子元素的 post 链接之前运行的逻辑

post-link

后链接

  1. directive that only has link function, angular treats the function as a post link

  2. post will be executed after compile, controller and pre-link funciton, so that's why this is considered the safest and default place to add your directive logic

  1. 仅具有链接功能的指令,angular 将该功能视为后链接

  2. post 将在编译、控制器和预链接函数之后执行,这就是为什么这被认为是添加指令逻辑的最安全和默认的地方