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

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

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

看起来templatecompilefunction非常相似,可以达到同样的效果。 template函数定义了一个模板, compile函数修改了模板DOM。 但是,它可以在template函数本身中完成。 我看不到为什么修改templatefunction以外的template DOM。 反之亦然,如果可以在compile函数中修改DOM,那么template函数需要什么?

在生成的模板函数绑定到作用域之前,可以使用编译函数来更改DOM。

考虑下面的例子:

 <div my-directive></div> 

您可以使用编译function来更改模板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>'); } } } }); 

所以,如果你的指令需要,你可以使用compilefunction将模板DOM更改为任何你喜欢的东西。

在大多数情况下, tElemiElem将是相同的DOM元素,但是有时候,如果一个指令克隆模板来删除多个副本(参见ngRepeat ),它可能会有所不同。

在幕后,Angular使用双向渲染过程(编译+链接)来压缩已编译的DOM片段的副本,以防止Angular必须对每个实例一遍又一遍地处理(=parsing指令)相同的DOM如果指令戳出多个克隆导致更好的性能。

希望有所帮助!


添加后评论:

templatecompile函数的区别:

模板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'; } } 

编译function

 { compile: function(tElem, tAttrs){ // Manipulate DOM of the element yourself // and return linking function return linkFn(){}; } } 

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

虽然他们可以执行几乎相同的东西并共享相同的“签名”,但关键的区别在于,模板函数的返回值将replace指令的内容(或者如果replace: true ,则为完整的指令标记),而编译函数预计将以编程方式更改DOM,并返回一个链接函数(或带有链接前后链接函数的对象)。

从这个意义上说,如果你只需要用string值replace内容,就可以将模板函数想象成某种方便的函数,而不必使用编译函数。

希望有所帮助!

模板函数的最佳用法之一是有条件地生成一个模板。 这使您可以根据属性自动创build模板。

我看到一些非常大的使用ng-if的模板来隐藏模板的各个部分。 但相反,它将所有东西扔进模板,并使用ng-if ,这可能会导致过多的绑定,您可以从模板中删除部分DOM将永远不会被使用。

假设您有一个指令,将包含子指令item-firstitem-second 。 而且这个子命令不会改变外部命令的生效。 在调用编译函数之前,您可以调整模板。

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

而这些模板string将是:

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

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

我同意这是一个极端简化,但我有一些非常复杂的指令,外部指令需要显示基于types的大约20个不同的内部指令之一。 而不是使用transclude,我可以在外部指令中设置types,并使模板函数使用正确的内部指令生成正确的模板。

然后将格式正确的模板string传递给编译函数等。