我认为这是我用angularjs指令理解的最难的概念之一。
来自http://docs.angularjs.org/guide/directive的文件说:
transclude - 编译元素的内容并使其可用于指令。通常与ngTransclude一起使用。翻译的优点是链接功能接收预先绑定到正确范围的翻译功能。在典型的设置中,窗口小部件创建隔离范围,但是转换不是子项,而是隔离范围的兄弟。这使得窗口小部件可以具有私有状态,并且将转换绑定到父(预隔离)范围。
- true - 转换指令的内容。
- 'element' - 转换整个元素,包括以较低优先级定义的任何指令。
它说transclude
通常与ngTransclude
一起使用。但是来自ngTransclude文档的示例根本不使用ngTransclude
指令。
我想要一些很好的例子来帮助我理解这一点。我们为什么需要它?它解决了什么?怎么用?
答案 0 :(得分:494)
在元素中考虑一个名为 myDirective 的指令,该元素包含一些其他内容,比方说:
<div my-directive>
<button>some button</button>
<a href="#">and a link</a>
</div>
如果 myDirective 正在使用模板,您会看到<div my-directive>
的内容将被您的指令模板替换。所以:
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>
的内容将丢失(或更好地说,替换)。所以,告别这些伙伴们:
<button>some button</button>
<a href="#">and a link</a>
那么,如果您希望将<button>...
和<a href>...
保留在DOM中,该怎么办?你需要一些叫做翻译的东西。这个概念非常简单:将内容从一个地方包含到另一个地方。所以现在你的指令看起来像这样:
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。
答案 1 :(得分:75)
我认为在新版本的AngularJS中提及上述行为的变化非常重要。我花了一个小时试图用Angular 1.2.10获得上述结果。
带有ng-transclude的元素的内容不会被附加,但会被完全替换。
所以在上面的例子中,你用'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>
感谢。
答案 2 :(得分:36)
TechExplorer所说的是正确的,但您可以通过在模板中包含带有ng-transclude属性的简单容器标记(如div或span)来同时拥有这两个内容。这意味着模板中的以下代码应包含所有内容
<div class="something"> This is my directive content <div class="something" ng-transclude></div></div>
答案 3 :(得分:5)
来自维基:
“在计算机科学中,包含部分或全部包含在内 通过引用将电子文件分成一个或多个其他文件。“
我想添加另一个用于转义的用法,那就是它改变了父指令和子指令的编译和链接函数的执行顺序。当您想在父DOM之前编译子DOM时,这可能很有用,因为父DOM可能依赖于子DOM。本文更深入,更清楚地阐明了它!
答案 4 :(得分:3)
Updated AngularJS 1.6.6 documentation现在有更好的解释。
Transclude用于创建包含其他元素的指令
有时候能够传入整个模板而不是字符串或对象是可取的。让我们说我们想创建一个&#34;对话框&#34;零件。该对话框应该能够包装任意内容。
为此,我们需要使用转换选项。请参阅下面的示例。
的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>
MY-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}}是杰夫。但是,我们在此示例中看到{{name}}绑定仍然是Tobias。
最佳实践:当您要创建包含任意内容的指令时,仅使用transclude: true
。
答案 5 :(得分:0)
transclude:true表示使用指令的template元素添加指令中定义的所有元素。
如果transclude:false这些元素不包含在最终的html指令中,只会呈现指令模板。
transclude:element表示您的指令模板不仅用于定义的元素 在你的指令中呈现为html。
当您定义指令时,它应该限制为E,当您在页面上添加它时
<my-directive><elements><my-directive>
<elements> is like <p>gratitude</p>
what i am talking about.