简体   繁体   English

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

[英]What are the benefits of a directive template function in Angularjs?

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.根据文档, template可以是一个函数,它接受两个参数,一个elementattributes并返回一个表示模板的字符串值。 It replaces the current element with the contents of the HTML.它将当前元素替换为 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. compile函数处理模板 DOM 的转换。 It takes three parameters, an element , attributes and transclude function.它需要三个参数,一个elementattributestransclude函数。 The transclude parameter has been deprecated. transclude参数已被弃用。 It returns a link function.它返回一个link函数。

It appears that a template and a compile functions are very similar and can achieve the same goal.看起来templatecompile功能非常相似,可以实现相同的目标。 The template function defines a template and compile function modifies the template DOM. template函数定义模板, compile函数修改模板DOM。 However, it can be done in the template function itself.但是,它可以在template函数本身中完成。 I can't see why modify the template DOM outside the template function.我不明白为什么要在template函数之外修改模板 DOM。 And vice-versa if the DOM can be modified in the compile function then what's the need for a template function?反之亦然,如果 DOM 可以在compile函数中修改,那么对template函数的需求是什么?

The compilation function can be used to change the DOM before the resulting template function is bound to the scope.编译函数可用于在生成的模板函数绑定到作用域之前更改 DOM。

Consider the following example:考虑以下示例:

<div my-directive></div>

You can use the compile function to change the template DOM like this:您可以使用 compile 函数来更改模板 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>');
      }
    }
  }
});

So you can use the compile function to change the template DOM to whatever you like if your directive requires it.因此,如果您的指令需要,您可以使用compile函数将模板 DOM 更改为您喜欢的任何内容。

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 ).在大多数情况下, tElemiElem将是相同的 DOM 元素,但有时如果指令克隆模板以删除多个副本(参见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.在幕后,Angular 使用 2 路渲染过程(编译 + 链接)来标记已编译的 DOM 片段的副本,以防止 Angular 必须为每个实例一遍又一遍地处理(= 解析指令)相同的 DOM如果该指令消除了多个克隆,从而获得更好的性能。

Hope that helps!希望有帮助!


ADDED AFTER COMMENT:评论后添加:

The difference between a template and compile function: templatecompile函数的区别:

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).尽管它们可以执行几乎相同的事情并共享相同的“签名”,但关键区别在于模板函数的返回值将替换指令的内容(或完整的指令标记,如果replace: true ),而编译函数预计以编程方式更改 DOM 并返回链接函数(或具有前后链接函数的对象)。

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.从这个意义上说,如果您只需要用字符串值替换内容,您可以将模板函数视为某种便利函数,无需使用 compile 函数。

Hope that helps!希望有帮助!

One of the best uses of the template function is to conditionally generate a template.模板函数的最佳用途之一是有条件地生成模板。 This allows you to automate the creation of a template based on an attribute or any other condition.这允许您根据属性或任何其他条件自动创建模板。

I have seen some very large templates that use ng-if to hide sections of the template.我见过一些非常大的模板,它们使用ng-if来隐藏模板的各个部分。 But instead of placing everything into the template and using ng-if , which can cause excessive binding, you can remove sections of the DOM from the output of the template function that will never be used.但是,不是将所有内容都放入模板并使用ng-if ,这会导致过度绑定,您可以从模板函数的输出中删除永远不会使用的 DOM 部分。

Let's say you have a directive that will include either sub-directive item-first or item-second .假设您有一个包含子指令item-firstitem-second的指令。 And the sub-directive will not ever change for the life of the outer directive.并且子指令在外部指令的生命周期内永远不会改变。 You can adjust the output of the template, prior to the compile function being called.您可以在调用编译函数之前调整模板的输出。

<my-item data-type="first"></my-item>
<my-item data-type="second"></my-item>

And the template string for these would be:这些模板字符串将是:

<div>
  <item-first></item-first>
</div>

and

<div>
  <item-second></item-second>
</div>

I agree that this is an extreme simplification, But I have some very complicated directives and the outer directive needs to display one of, about, 20 different inner directives based on a type.我同意这是一种极端的简化,但是我有一些非常复杂的指令,并且外部指令需要根据类型显示大约 20 个不同的内部指令之一。 Instead of using transclude, I can set the type on the outer directive and have the template function generate the correct template with the correct inner directive.我可以不使用 transclude,而是在外部指令上设置类型,并让模板函数使用正确的内部指令生成正确的模板。

That correctly formatted template string is then passed on to the compile function, etc.然后将该格式正确的模板字符串传递给编译函数等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM