Angular JS:当我们已经有了带范围的指令控制器时,指令的链接功能有什么需求?

2020/10/16 16:01 · javascript ·  · 0评论

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

什么时候需要使用link功能而不是控制器?

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 */ }
    };
}

另外,我知道那link是非角度的世界。所以,我可以使用$watch$digest$apply

link当我们已经有了控制器时,该功能的意义是什么

函数进行了最初的斗争并阅读了很多有关它们的内容之后,我想现在我有了答案。linkcontroller

首先让理解

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

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

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

  • 现在,将templateString其包装为角形元素

    var el = angular.element(templateString);

  • 使用el,现在我们用$compile进行编译,以获取链接功能。

    var l = $compile(el)

    这是发生了什么事

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

    l(scope)

  • 这会将template作为新节点添加到,DOM并进行调用controller,并将其监视值添加到与DOM中的模板共享范围

在此处输入图片说明

比较compile vs linkcontroller

  • 每个指令只能编译一次,链接功能将保留以供重复使用。因此,如果某条指令适用于指令的所有实例,则应在指令的compile功能内执行

  • 现在,在编译之后,我们有了link模板附加DOM时执行的功能因此,因此我们执行特定于指令每个实例的所有操作。例如:附加事件基于范围更改模板等。

  • 最后,当指令在上运行时(附加后),该控制器应处于活动状态和反应状态DOM因此:

    (1)设置带有链接的视图[ V ](即模板)后。$scope是我们的[ M ],$controller也是我们MVC中的[ C ]

    (2)通过设置手表利用$ scope2向绑定

    (3)$scope期望在控制器中添加监视,因为这是在运行时监视模板。

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

    (5)的确,我们也可以在link函数中完成所有这些操作,它只涉及关注点分离

因此,最后我们可以完美地满足所有需求:

在此处输入图片说明

为什么需要控制器

之间的差异linkcontroller当你想在你的DOM巢指令和从父指令嵌套那些暴露的API函数的用武之地。

文档

最佳实践:要向其他指令公开API时,请使用控制器。否则使用链接。

假设您要有两个指令my-formmy-text-input并且希望my-text-input指令仅出现在内部,my-form而没有其他地方。

在这种情况下,您将在定义指令时my-text-input说它需要parent使用require参数DOM元素中获取控制器,如下所示:require: '^myForm'现在,来自父元素的控制器将作为第四个参数injected进入link函数,其后是$scope, element, attributes您可以在该控制器上调用函数并与父指令进行通信。

此外,如果未找到这样的控制器,则会引发错误。

为什么要使用链接

link如果正在定义,则不需要真正使用该功能,controller因为$scope可以在上使用controller此外,在定义link和时controller,确实需要注意两者的调用顺序(controller之前已执行)。

但是,与Angular方式保持一致,大多数DOM操纵和2向绑定使用$watchers通常是在link函数中完成的,而用于子项和$scope操纵的API则是在中完成的controller这不是一成不变的规则,但是这样做会使代码更具模块化,并有助于分离关注点(控制器将维护directive状态,link函数将维护DOM+外部绑定)。

controller功能/对象表示一个抽象模型-视图-控制器(MVC)。尽管没有什么新的关于MVC的文章可以写,但是它仍然是angular的最重要的优势:将关注点分成更小的部分。就是这样,仅此而已,因此,如果您需要对Model来自View更改做出反应Controller是合适的来完成这项工作。

关于link功能的故事是不同的,它与MVC来自不同的角度。一旦我们想跨越controller/model/view (模板)的边界,这真的很重要

让我们从传递给link函数的参数开始

function link(scope, element, attrs) {
  • scope是Angular作用域对象。
  • element是此伪指令匹配的jqLit​​e包装的元素。
  • attrs是具有规范化属性名称及其对应值的对象。

要把link上下文放到上下文中,我们应该提到所有指令都通过了初始化过程:CompileLinkBrad Green和Shyam Seshadri的《 Angular JS》摘录

编译阶段(链接的姐妹,让我们在这里提到它以获得清晰的图片):

在此阶段,Angular遍历DOM以标识模板中所有已注册的指令。然后,对于每个指令,它根据指令的规则(模板,替换,转写等)转换DOM,并调用编译函数(如果存在)。结果是一个编译的模板函数,

链接阶段

为了使视图动态化,Angular然后为每个指令运行一个链接函数。链接功能通常在DOM或模型上创建侦听器。这些侦听器始终保持视图和模型同步。

link可以在这里找到如何使用的好示例创建自定义指令请参见示例:创建操纵DOM的指令,该指令将“日期时间”插入页面,并且每秒刷新一次。

上面的丰富资源中仅一小段,显示了DOM的实际操作。$ timeout服务有钩子函数,并且在其析构函数调用中将其清除以避免内存泄漏

.directive('myCurrentTime', function($timeout, dateFilter) {

 function link(scope, element, attrs) {

 ...

 // the not MVC job must be done
 function updateTime() {
   element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
 }

 function scheduleUpdate() {
   // save the timeoutId for canceling
   timeoutId = $timeout(function() {
     updateTime(); // update DOM
     scheduleUpdate(); // schedule the next update
   }, 1000);
 }

 element.on('$destroy', function() {
   $timeout.cancel(timeoutId);
 });

 ...
本文地址:http://javascript.askforanswer.com/angular-jsdangwomenyijingyouledaifanweidezhilingkongzhiqishizhilingdelianjiegongnengyoushenmexu.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!