ChatGPT解决这个技术问题 Extra ChatGPT

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

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


C
Community

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

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

链接函数 - 通常用于注册侦听器回调(即,作用域上的 $watch 表达式)以及更新 DOM(即,操作 iElement = 单个实例元素)。它在模板被克隆后执行。例如,在

  • 内,链接函数在
  • 模板 (tElement) 被克隆(到 iElement)用于特定的
  • 元素之后执行。 $watch 允许指令通知范围属性更改(范围与每个实例相关联),这允许指令将更新的实例值呈现给 DOM。

    控制器功能 - 当另一个指令需要与该指令交互时必须使用。例如,在 AngularJS 主页上,pane 指令需要将自身添加到 tabs 指令维护的范围内,因此 tabs 指令需要定义一个控制器方法(想想 API),pane 指令可以访问/调用。有关选项卡和窗格指令的更深入解释,以及为什么选项卡指令使用 this(而不是 $scope)在其控制器上创建函数,请参阅 AngularJS 控制器中的“this”与 $scope。

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


    这个解释应该在主要的 AngularJS 文档中,或者至少是对它的引用
    这是一个内容丰富的答案,但我认为很难阅读。也许更多的标点符号和更小的句子会有所帮助。总的来说,我很感谢您的回答。
    $compiler 在存在 'compile' 属性的情况下会忽略 'link' 属性。但是在存在“控制器”属性的情况下呢? “控制器”是否会导致 $compiler 忽略“链接”和“编译”属性中的一个或两个?是否可以和/或建议将“编译”与“控制器”一起使用?
    @CarlG,关于链接和编译,控制器属性的存在对 $compiler 没有影响。您可以使用编译和控制器。
    “DOM 侦听器”不是“(即作用域上的 $watch 表达式)”。一个监听 DOM 中的 mouseover 等事件,另一个监听属性更改的范围。巨大差距。
  • P
    Pixic

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

    我真的推荐这个视频; Writing Directives 由 Misko Hevery(AngularJS 之父)撰写,他在其中描述了差异和一些技术。 (14:41 mark in the video 处的编译函数和链接函数之间的区别)。


    +1 视频链接。这是非常有用的。
    R
    Rahul

    编译前运行代码:使用控制器编译后运行代码:使用链接

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

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

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

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

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


    “编译前运行代码:使用控制器”。这是不正确的; compile 将始终在 controller 之前执行。
    您将无法(至少不是以直接的方式)能够从您的豹指令访问动物。子指令可以访问父指令中的控制器方法,但兄弟指令(如上面的示例中)不能调用彼此的控制器。
    豹子真的是豹子的一种吗?另外,在旁注中...您可以在指令中有一个链接 - 并且 - 一个控制器吗?
    是的豹/美洲虎是豹。是的,您在指令中有链接和控制器。
    来自 Angular 开发人员指南:“最佳实践:当您想将 API 公开给其他指令时使用控制器。否则使用链接。”
    S
    Sunil Garg

    编译函数——

    在控制器和链接函数之前调用。在 compile 函数中,您拥有原始模板 DOM,因此您可以在 AngularJS 创建它的实例之前和创建范围之前对原始 DOM 进行更改 ng-repeat 是完美的示例 - 原始语法是模板元素,HTML 中的重复元素是实例可以有多个元素实例,并且只有一个模板元素范围尚不可用编译函数可以返回函数和对象返回(链接后)函数 - 相当于通过配置对象的链接属性注册链接函数时编译函数为空。返回具有通过 pre 和 post 属性注册的函数的对象 - 允许您控制在链接阶段何时应调用链接函数。请参阅下面有关预链接和后链接功能的信息。

    句法

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

    控制器

    在此处编译函数范围可用后调用可以被其他指令访问(请参阅 require 属性)

    预链接

    链接函数负责注册 DOM 监听器以及更新 DOM。它在模板被克隆后执行。这是放置大部分指令逻辑的地方。您可以使用 angular.element 更新控制器中的 dom,但不建议这样做,因为该元素是在链接函数中提供的预链接函数用于实现在 angular js 已经编译子元素但在任何之前运行的逻辑子元素的帖子链接已被调用

    后链接

    仅具有链接功能的指令,角度将功能视为发布链接发布将在编译,控制器和预链接功能之后执行,因此这就是为什么这被认为是添加指令逻辑的最安全和默认位置