Angular JS:当我们已经有了带作用域的指令控制器时,指令的链接函数还需要什么? [英] Angular JS: What is the need of the directive’s link function when we already had directive’s controller with scope?

查看:20
本文介绍了Angular JS:当我们已经有了带作用域的指令控制器时,指令的链接函数还需要什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要对作用域和模板执行一些操作.似乎我可以在 link 函数或 controller 函数中做到这一点(因为两者都可以访问范围).

什么时候我必须使用link函数而不是控制器?

angular.module('myApp').directive('abc', function($timeout) {返回 {限制:'EA',替换:真的,转置:真实,范围:真实,链接:函数(范围,元素,属性){/* 链接函数 */},控制器:函数($scope,$element){/* 控制器函数 */}};}

另外,我知道 link 是无角的世界.所以,我可以使用 $watch$digest$apply.

当我们已经有了控制器时,link 函数的意义是什么?

解决方案

在我初始linkcontroller 功能和阅读的斗争之后很多关于他们的事情,我想现在我有了答案.

首先让了解

简而言之,角度指令是如何工作的:

  • 我们从模板开始(作为字符串或加载到字符串)

    var templateString = '

    {{5 + 10}}

    ';

  • 现在,这个templateString被包装成一个角度元素

    var el = angular.element(templateString);

  • 使用el,现在我们使用$compile 编译它以取回link 函数.

    var l = $compile(el)

    这是发生了什么,

    • $compile 遍历整个模板并收集它识别的所有指令.
    • 所有发现的指令都递归编译,并收集它们的link函数.
    • 然后,所有的 link 函数都被包装在一个新的 link 函数中,并作为 l 返回.
  • 最后,我们为这个 l(链接)函数提供了 scope 函数,该函数进一步使用这个 scope 执行包装的链接函数以及它们对应的元素.

    l(范围)

  • 这会将 template 作为一个新节点添加到 DOM 并调用 controller,后者将其监视添加到 范围,与 DOM 中的模板共享.

比较编译链接控制器:

  • 每个指令只编译一次,链接函数被保留以供重复使用.因此,如果有一些适用于指令的所有实例的东西应该在指令的 compile 函数中执行.

  • 现在,编译后我们有 link 函数,该函数在将 模板 附加到 DOM 时执行.因此,我们执行针对指令的每个实例的所有操作.例如:附加事件根据作用域改变模板

  • 最后,当指令在 DOM 上工作时(附加后),控制器 是可用的.因此:

    (1) 使用链接设置视图[V](即模板)后.$scope 是我们的 [M] 而 $controller 是我们在 MVC 中的 [C]强>

    (2) 通过设置手表来利用 2-way$scope 的绑定.

    (3) $scope 预计将添加到控制器中,因为这是在运行时监视模板的内容.

    (4) 最后,controller 也用于能够在相关指令之间进行通信.(就像 https://docs.angularjs.org/guide/directive 中的 myTabs 示例)

    (5) 确实,我们也可以在 link 函数中完成所有这些,但它是关于关注点分离.

因此,最后我们有以下完美适合所有部分的内容:

I need to perform some operations on scope and the template. It seems that I can do that in either the link function or the controller function (since both have access to the scope).

When is it the case when I have to use link function and not the controller?

angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}

Also, I understand that link is the non-angular world. So, I can use $watch, $digest and $apply.

What is the significance of the link function, when we already had controller?

解决方案

After my initial struggle with the link and controller functions and reading quite a lot about them, I think now I have the answer.

First lets understand,

How do angular directives work in a nutshell:

  • We begin with a template (as a string or loaded to a string)

    var templateString = '<div my-directive>{{5 + 10}}</div>';

  • Now, this templateString is wrapped as an angular element

    var el = angular.element(templateString);

  • With el, now we compile it with $compile to get back the link function.

    var l = $compile(el)

    Here is what happens,

    • $compile walks through the whole template and collects all the directives that it recognizes.
    • All the directives that are discovered are compiled recursively and their link functions are collected.
    • Then, all the link functions are wrapped in a new link function and returned as l.
  • Finally, we provide scope function to this l (link) function which further executes the wrapped link functions with this scope and their corresponding elements.

    l(scope)

  • This adds the template as a new node to the DOM and invokes controller which adds its watches to the scope which is shared with the template in DOM.

Comparing compile vs link vs controller :

  • Every directive is compiled only once and link function is retained for re-use. Therefore, if there's something applicable to all instances of a directive should be performed inside directive's compile function.

  • Now, after compilation we have link function which is executed while attaching the template to the DOM. So, therefore we perform everything that is specific to every instance of the directive. For eg: attaching events, mutating the template based on scope, etc.

  • Finally, the controller is meant to be available to be live and reactive while the directive works on the DOM (after getting attached). Therefore:

    (1) After setting up the view[V] (i.e. template) with link. $scope is our [M] and $controller is our [C] in M V C

    (2) Take advantage the 2-way binding with $scope by setting up watches.

    (3) $scope watches are expected to be added in the controller since this is what is watching the template during run-time.

    (4) Finally, controller is also used to be able to communicate among related directives. (Like myTabs example in https://docs.angularjs.org/guide/directive)

    (5) It's true that we could've done all this in the link function as well but its about separation of concerns.

Therefore, finally we have the following which fits all the pieces perfectly :

这篇关于Angular JS:当我们已经有了带作用域的指令控制器时,指令的链接函数还需要什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆