javascript - Angularjs 中的指令模板函数有什么好处?

标签 javascript angularjs templates compilation directive

根据文档,template 可以是一个函数,它接受两个参数,一个 elementattributes 并返回一个字符串值,表示模板。它用 HTML 的内容替换当前元素。替换过程将所有属性和类从旧元素迁移到新元素。

compile 函数处理转换模板 DOM。它采用三个参数,elementattributestransclude 函数。 transclude 参数已被弃用。它返回一个 link 函数。

看起来templatecompile 功能非常相似,可以实现相同的目标。 template 函数定义一个模板,compile 函数修改模板 DOM。但是,它可以在 template 函数本身中完成。我不明白为什么要在 template 函数之外修改模板 DOM。反之亦然,如果可以在 compile 函数中修改 DOM,那么还需要什么 template 函数?

最佳答案

编译函数可用于在生成的模板函数绑定(bind)到作用域之前更改 DOM。

考虑以下示例:

<div my-directive></div>

您可以使用编译函数来更改模板 DOM,如下所示:

app.directive('myDirective', function(){
  return {

    // Compile function acts on template DOM
    // This happens before it is bound to the scope, so that is why no scope
    // is injected
    compile: function(tElem, tAttrs){

      // This will change the markup before it is passed to the link function
      // and the "another-directive" directive will also be processed by Angular
      tElem.append('<div another-directive></div>');

      // Link function acts on instance, not on template and is passed the scope
      // to generate a dynamic view
      return function(scope, iElem, iAttrs){

        // When trying to add the same markup here, Angular will no longer
        // process the "another-directive" directive since the compilation is
        // already done and we're merely linking with the scope here
        iElem.append('<div another-directive></div>');
      }
    }
  }
});

因此,如果指令需要,您可以使用compile 函数将模板 DOM 更改为您喜欢的任何内容。

在大多数情况下,tElemiElem 将是相同的 DOM 元素,但有时如果指令克隆模板以消除多个副本,它可能会有所不同(cf. ngRepeat).

在幕后,Angular 使用双向渲染过程(编译 + 链接)来消除已编译的 DOM 片段的副本,以防止 Angular 不得不一遍又一遍地处理(= 解析指令)相同的 DOM对于每个实例,以防指令消除多个克隆,从而获得更好的性能。

希望对您有所帮助!


评论后添加:

模板编译函数的区别:

模板函数

{
    template: function(tElem, tAttrs){

        // Generate string content that will be used by the template
        // function to replace the innerHTML with or replace the
        // complete markup with in case of 'replace:true'
        return 'string to use as template';
    }
}

编译函数

{
    compile: function(tElem, tAttrs){

        // Manipulate DOM of the element yourself
        // and return linking function
        return linkFn(){};
    }
}

在调用编译函数之前调用模板函数。

虽然它们可以执行几乎相同的事情并共享相同的“签名”,但关键区别在于模板函数的返回值将替换指令的内容(如果 replace: true,则替换完整的指令标记),而编译函数应该以编程方式更改 DOM 并返回链接函数(或具有前后链接功能的对象)。

从这个意义上说,您可以将模板函数视为某种便利函数,如果您只需要用字符串值替换内容,则不必使用编译函数。

希望对您有所帮助!

关于javascript - Angularjs 中的指令模板函数有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20941568/

相关文章:

c++ - 重载通用句柄类的赋值运算符

C++函数装饰器

javascript - GraphQL : Reuse arguments from root_query in a type

javascript - JQUERY HTML DIV 根据标签值隐藏和显示

javascript - Angular JS 基于单选按钮状态突出显示行

javascript - 带有可选范围值的指令和使用 html 中的文字设置的困难

angularjs - Google map setCenter 未正确将 map 居中

c++ - 在编译时自动生成用于稀疏数组索引的 switch 语句

javascript - EaselJS 中的注册点是什么?

javascript - ReactJS 安装和矫枉过正的复杂性