理解指令定义的transclude选项?

我认为这是我用angularjs的指令理解的最难的概念之一。

来自http://docs.angularjs.org/guide/directive的文件说:

transclude – 编译元素的内容并使其可用于指令。 通常与ngTransclude一起使用。 转换的优点是链接函数接收到一个预先绑定到正确范围的转换函数。 在一个典型的设置中,小部件会创build一个隔离范围,但是该隔离不是一个孩子,而是隔离范围的一个兄弟。 这使小部件具有私有状态成为可能,并且将该跨部分绑定到父(预分离)范围。

  • 真 – transclude该指令的内容。
  • “元素” – 涵盖整个元素,包括以较低优先级定义的任何指令。

它说ngTransclude通常与ngTransclude一起ngTransclude 。 但是ngTransclude文档中的示例根本不使用ngTransclude指令。

我想要一些很好的例子来帮助我理解这一点。 我们为什么需要它? 它解决了什么问题? 如何使用它?

在一个元素中考虑一个名为myDirective的指令,该元素包含了一些其他内容,比如说:

 <div my-directive> <button>some button</button> <a href="#">and a link</a> </div> 

如果myDirective正在使用模板,则会看到<div my-directive>将被指令模板replace。 所以有:

 app.directive('myDirective', function(){ return{ template: '<div class="something"> This is my directive content</div>' } }); 

会导致这个渲染:

 <div class="something"> This is my directive content</div> 

请注意,原始元素<div my-directive> 将会丢失 (或者更好地说,replace)。 所以,告诉这些哥们:

 <button>some button</button> <a href="#">and a link</a> 

那么,如果你想保持你的<button>...<a href>...在DOM中? 你需要一个叫做transclusion的东西。 这个概念非常简单: 将内容从一个地方放入另一个地方 。 所以现在你的指令看起来像这样:

 app.directive('myDirective', function(){ return{ transclude: true, template: '<div class="something"> This is my directive content</div> <ng-transclude></ng-transclude>' } }); 

这会使得:

 <div class="something"> This is my directive content <button>some button</button> <a href="#">and a link</a> </div>. 

总之,当你使用一个指令的时候,当你想保留一个元素的内容时,你基本上使用transclude。

我的代码示例在这里http://jsfiddle.net/7LRDS/1/你也可以从看:; https : //egghead.io/lessons/angularjs-transclusion-basics

我认为在新版本的AngularJS中提到上述行为的变化是很重要的。 我花了一个小时试图用Angular 1.2.10获得上述结果。

ng-transclude元素的内容不被附加,而是被完全replace。

所以在上面的例子中,用'transclude'可以实现的是:

 <div class="something"> <button>some button</button> <a href="#">and a link</a> </div> 

并不是

 <div class="something"> This is my directive content <button>some button</button> <a href="#">and a link</a> </div> 

谢谢。

什么TechExplorer说是真实的,但你可以通过在你的模板中包含ng-transclude属性的简单的容器标签(如div或跨度)的两个内容。 这意味着您的模板中的以下代码应包含所有内容

 <div class="something"> This is my directive content <div class="something" ng-transclude></div></div> 

来自Wiki:

“在计算机科学中,跨部门是通过引用将电子文档的部分或全部纳入一个或多个其他文档。”

我想添加另一个用于transclusion的用法,那就是它改变了parent和child指令的编译和链接函数的执行顺序。 当您想要在父DOM之前编译子DOM时,这可能很有用,因为父DOM可能依赖于子DOM。 这篇文章更深入,并澄清它!

http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives-part-2-transclusion/

更新的AngularJS 1.6.6文档现在有一个更好的解释。

Transclude用于创build包装其他元素的指令

有时需要能够传入整个模板而不是string或对象。 假设我们要创build一个“对话框”组件。 对话框应该能够包装任意的内容。

为此,我们需要使用transclude选项。 参考下面的例子。


的script.js

 angular.module('docsTransclusionExample', []) .controller('Controller', ['$scope', function($scope) { $scope.name = 'Tobias'; }]) .directive('myDialog', function() { return { restrict: 'E', transclude: true, scope: {}, templateUrl: 'my-dialog.html', link: function(scope) { scope.name = 'Jeff'; } }; }); 

的index.html

 <div ng-controller="Controller"> <my-dialog>Check out the contents, {{name}}!</my-dialog> </div> 

我-dialog.html

 <div class="alert" ng-transclude></div> 

编译输出

 <div ng-controller="Controller" class="ng-scope"> <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog> </div> 

Transclude使用此选项的指令内容可以访问指令外的范围而不是内部。

在前面的例子中说明了这一点。 请注意,我们在script.js中添加了一个链接函数,该函数将名称重新定义为Jeff。 通常我们会期望{{name}}是Jeff。 但是,在这个例子中我们看到{{name}}绑定仍然是Tobias。

最佳实践 :仅当您要创build包装任意内容的指令时才使用transclude: true

transclude:真正的意思是添加你的指令中定义的所有元素与你的指令的模板元素。

如果transclude:false这些元素不包含在你的指令的最后的html中,那么只有指令的模板被呈现。

transclude:元素意思是你的指令模板不是只用在你的指令中定义的元素呈现为html。

当你定义你的指令时,它应该被限制到E,并且当你在页面上添加它

 <my-directive><elements><my-directive> <elements> is like <p>gratitude</p> what i am talking about.