有些地方似乎使用控制器功能指令逻辑和其他使用链接。angular主页上的选项卡例子中,一个指令使用controller,另一个指令使用link。这两者之间有什么区别?


当前回答

编译函数-

is called before the controller and link function. 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 ng-repeat is perfect example - original syntax is template element, the repeated elements in HTML are instances There can be multiple element instances and only one template element Scope is not available yet Compile function can return function and object 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. 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.

语法

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

控制器

在编译函数之后调用 范围在这里 可以被其他指令访问(参见require属性)

上一页 - 链接

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. 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 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

post-link

指令只有链接函数,angular会将该函数视为post链接 Post将在编译、控制器和预链接函数之后执行,所以这就是为什么这里被认为是添加指令逻辑的最安全的默认位置

其他回答

编译函数-

is called before the controller and link function. 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 ng-repeat is perfect example - original syntax is template element, the repeated elements in HTML are instances There can be multiple element instances and only one template element Scope is not available yet Compile function can return function and object 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. 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.

语法

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

控制器

在编译函数之后调用 范围在这里 可以被其他指令访问(参见require属性)

上一页 - 链接

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. 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 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

post-link

指令只有链接函数,angular会将该函数视为post链接 Post将在编译、控制器和预链接函数之后执行,所以这就是为什么这里被认为是添加指令逻辑的最安全的默认位置

我将稍微扩展一下您的问题,并包括compile函数。

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. (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., $watch expressions 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 $watch allows 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.

一般来说,你可以把方法,$watches等放在指令的控制器或链接函数中。控制器将首先运行,这有时很重要(请参阅此fiddle,当ctrl和link函数使用两个嵌套指令运行时,它会记录日志)。正如Josh在评论中提到的,为了与框架的其余部分保持一致,您可能希望将作用域操作函数放在控制器中。

在编译之前运行代码:使用控制器 编译后运行代码:使用Link

Angular约定:在controller中写业务逻辑,在link中写DOM操作。

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

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

你想从“豹子”指令中获取动物。

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

作为Mark回答的补充,compile函数不能访问作用域,但是link函数可以。

我非常推荐这个视频;Misko Hevery (AngularJS之父)编写的指令,他描述了不同之处和一些技术。(视频中14:41标记的编译函数和链接函数的区别)。