Javascript angularjs中编译函数和链接函数的区别是什么

Javascript angularjs中编译函数和链接函数的区别是什么,javascript,angularjs,Javascript,Angularjs,有人能简单地解释一下吗 这些文件似乎有点迟钝。我还没有弄清楚什么时候应该用一个来代替另一个。一个对比这两者的例子将非常棒。 编译程序 编译器是一个角度服务,它遍历DOM查找属性。编译过程分为两个阶段 编译:遍历DOM并收集所有指令。结果是一个链接函数 链接:将指令与作用域相结合,生成实时视图。范围模型中的任何更改都会反映在视图中,用户与视图的任何交互都会反映在范围模型中。使范围模型成为真理的单一来源 有些指令,例如为集合中的每个项克隆一次DOM元素。拥有编译和链接阶段可以提高性能,因为克隆的模板

有人能简单地解释一下吗

这些文件似乎有点迟钝。我还没有弄清楚什么时候应该用一个来代替另一个。一个对比这两者的例子将非常棒。

编译程序 编译器是一个角度服务,它遍历DOM查找属性。编译过程分为两个阶段

  • 编译:遍历DOM并收集所有指令。结果是一个链接函数

  • 链接:将指令与作用域相结合,生成实时视图。范围模型中的任何更改都会反映在视图中,用户与视图的任何交互都会反映在范围模型中。使范围模型成为真理的单一来源

  • 有些指令,例如为集合中的每个项克隆一次DOM元素。拥有编译和链接阶段可以提高性能,因为克隆的模板只需要编译一次,然后为每个克隆实例链接一次

    因此,至少在某些情况下,这两个阶段作为优化单独存在。


    :

    如果要进行DOM转换,则应该是
    compile
    。如果您想添加一些行为改变的功能,应该在
    链接中添加

    • 编译函数-用于模板DOM操纵(即操纵tElement=template元素),因此操纵适用于与指令关联的模板的所有DOM克隆

    • 链接函数-用于注册DOM侦听器(即实例作用域上的$watch表达式)以及实例DOM操作(即IEElement=单个实例元素的操作)。
      它在克隆模板后执行。例如,在一个
    • ,链接函数在该
    • 元素的
    • 模板(tElement)被克隆(到一个IEElement)后执行。
      一个$watch()允许一个指令被通知实例作用域属性的变化(一个实例作用域与每个实例相关联),它允许指令向DOM呈现更新的实例值——通过将内容从实例范围复制到DOM中

    请注意,DOM转换可以在编译函数和/或链接函数中完成

    大多数指令只需要一个链接函数,因为大多数指令只处理特定的DOM元素实例(及其实例范围)

    帮助确定使用哪种方法:考虑编译函数不接收<代码>作用域< /> >参数。(我故意忽略transclude linking函数参数,它接收一个transclude作用域——这是使用的。)因此编译函数不能做任何需要(实例)作用域的事情——你不能$watch任何模型/实例作用域属性,你不能使用实例作用域信息操纵DOM,不能调用在实例范围等上定义的函数

    但是,编译函数(如link函数)确实可以访问这些属性。因此,如果DOM操作不需要实例范围,可以使用编译函数。出于这些原因,下面是一个仅使用编译函数的指令的示例。它检查属性,但不需要实例范围来完成其工作

    下面是一个也只使用编译函数的指令的示例。该指令只需要转换模板DOM,因此可以使用编译函数

    另一种帮助确定使用哪一个的方法:如果在link函数中不使用“element”参数,那么可能不需要link函数

    因为大多数指令都有一个链接函数,所以我不会提供任何示例——它们应该很容易找到

    请注意,如果需要编译函数和链接函数(或前后链接函数),则编译函数必须返回链接函数,因为如果定义了“compile”属性,“link”属性将被忽略

    另见

    • Dave Smith的优秀(链接到视频中有关编译和链接的部分)

      • 这是米斯科关于指令的谈话

        将编译器函数视为 在模板上工作的东西和允许 更改模板本身,例如,向其添加类或 诸如此类。但真正起作用的是链接功能 将两者绑定在一起的工作,因为链接函数 访问作用域,它是执行一次的链接函数 对于特定模板的每个实例化。所以唯一的 可以放在编译函数中的东西是 在所有实例中都是通用的


        我在这件事上撞了几天墙,我觉得有必要再多解释一下

        基本上,文档提到分离在很大程度上是一种性能增强。我要重申,编译阶段主要用于在编译子元素之前需要修改DOM的时候

        出于我们的目的,我要强调术语,否则会令人困惑:

        编译器服务($compile)是处理DOM并在指令中运行各种代码位的角度机制

        compile函数是指令中的一位代码,由编译器服务($compile)在特定时间运行

        关于编译函数的一些注意事项:

      • 您不能修改根元素(您的指令影响的元素),因为它已经从DOM的外部级别编译(编译服务已经扫描了该元素上的指令)

      • 如果要添加其他指令
        <tp>
           <sp>
           </sp>
        </tp>
        
        tp compile
        sp compile
        tp pre-link
        sp pre-link
        sp post-link
        tp post-link
        
        <div><span><input type="text"></span><div>
        
        <my-field model="state" name="address"></my-field>
        
        <div><span ng-show="state.visible.address"><input ng-model="state.fields.address" ...>
        
        compile: function(tele, tattr) {
           var span = jQuery(tele).find('span').first();
           span.attr('ng-show', tattr.model + ".visible." + tattr.name);
           ...
           return { 
             pre: function() { },
             post: function() {}
           };
        }
        
        directive('d', function($compile) {
          return {
            // REMEMBER, link is called AFTER nested elements have been compiled and linked!
            link: function(scope, iele, iattr) {
              var span = jQuery(iele).find('span').first();
              span.attr('ng-show', iattr.model + ".visible." + iattr.name);
              // CAREFUL! If span had directives on it before
              // you will cause them to be processed again:
              $compile(span)(scope);
            }
        });
        
        scope.metadata = {
          validations: {
             address: [ {
               pattern: '^[0-9]',
               message: "Address must begin with a number"
             },
             { maxlength: 100,
               message: "Address too long"
             } ]
          }
        };
        scope.state = {
          address: '123 Fern Dr'
        };
        
        <form name="theForm">
          <my-field model="state" metadata="metadata" name="address">
        </form>
        
        <form name="theForm">
          <div>
            <input ng-model="state.address" type="text">
            <div ng-show="theForm.address.$error.pattern">Address must begin with a number</input>
        ...
        
        angular.module('app', []).
        directive('my-field', function($compile) {
          return {
            link: function(scope, iele, iattr) {
              // jquery additions via attr()
              // remove ng attr from top-level iele (to avoid duplicate processing)
              $compile(iele)(scope); // will pick up additions
            }
          };
        });
        
        var app = angular.module('app', []); app.controller('msg', ['$scope', function($scope){ }]); app.directive('message', function($interpolate){ return{ compile: function(tElement, tAttributes){ console.log(tAttributes.text + " -In compile.."); return { pre: function(scope, iElement, iAttributes, controller){ console.log(iAttributes.text + " -In pre.."); }, post: function(scope, iElement, iAttributes, controller){ console.log(iAttributes.text + " -In Post.."); } } }, controller: function($scope, $element, $attrs){ console.log($attrs.text + " -In controller.."); }, } });
        <body ng-app="app">
        <div ng-controller="msg">
            <div message text="first">
                <div message text="..second">
                    <div message text="....third">
        
                    </div>              
                </div>  
            </div>
        </div>