且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-10-28 13:34:30

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

考虑以下示例:

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

app.directive('myDirective', function(){返回 {//编译函数作用于模板DOM//这发生在它绑定到作用域之前,所以这就是没有作用域的原因//被注入编译:函数(tElem,tAttrs){//这将在传递给链接函数之前更改标记//并且another-directive"指令也将由Angular处理tElem.append('<div another-directive></div>');//链接函数作用于实例,而不作用于模板并传递作用域//生成动态视图返回函数(范围,iElem,iAttrs){//当试图在这里添加相同的标记时,Angular 将不再//处理another-directive"指令,因为编译是//已经完成,我们只是在这里链接范围iElem.append('<div another-directive></div>');}}}});

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

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

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

希望有帮助!

评论后添加:

templatecompile 函数的区别:

模板函数

{模板:功能(tElem,tAttrs){//生成模板将使用的字符串内容//用或替换innerHTML的函数//在'replace:true'的情况下完成标记返回用作模板的字符串";}}

编译函数

{编译:函数(tElem,tAttrs){//自己操作元素的DOM//并返回链接函数返回linkFn(){};}}

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

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

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

希望有帮助!

According to the documentation a template can be a function which takes two parameters, an element and attributes and returns a string value representing the template. It replaces the current element with the contents of the HTML. The replacement process migrates all of the attributes and classes from the old element to the new one.

The compile function deals with transforming the template DOM. It takes three parameters, an element, attributes and transclude function. The transclude parameter has been deprecated. It returns a link function.

It appears that a template and a compile functions are very similar and can achieve the same goal. The template function defines a template and compile function modifies the template DOM. However, it can be done in the template function itself. I can't see why modify the template DOM outside the template function. And vice-versa if the DOM can be modified in the compile function then what's the need for a template function?

The compilation function can be used to change the DOM before the resulting template function is bound to the scope.

Consider the following example:

<div my-directive></div>

You can use the compile function to change the template DOM like this:

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>');
      }
    }
  }
});

So you can use the compile function to change the template DOM to whatever you like if your directive requires it.

In most cases tElem and iElem will be the same DOM element, but sometimes it can be different if a directive clones the template to stamp out multiple copies (cf. ngRepeat).

Behind the scenes, Angular uses a 2-way rendering process (compile + link) to stamp out copies of a compiled piece of DOM, to prevent Angular from having to process (= parse directives) the same DOM over and over again for each instance in case the directive stamps out multiple clones resulting in much better performance.

Hope that helps!


ADDED AFTER COMMENT:

The difference between a template and compile function:

Template function

{
    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

{
    compile: function(tElem, tAttrs){

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

The template function is called before the compile function is called.

Although they can perform almost identical stuff and share the same 'signature', the key difference is that the return value of the template function will replace the content of the directive (or the complete directive markup if replace: true), while a compile function is expected to change the DOM programmatically and return a link function (or object with pre and post link function).

In that sense you can think of the template function as some kind of convenience function for not having to use the compile function if you simply need to replace the content with a string value.

Hope that helps!