2014-02-27 51 views
33

我是Angular的新手,但阅读的内容相当多。 我正在阅读ng-transcludehttp://docs.angularjs.org/guide/directive#creating-custom-directives_demo_isolating-the-scope-of-a-directive,我想我正确理解它的功能。AngularJS:在单个Angular指令中跨多个子元素

如果您有适用于具有里面的内容,如在

<my-directive>directive content</my-directive> 

这将让你与ng-transclude标记指令的模板中的元素,并包含在元素中的内容元素的指令会在标签元素内呈现。

所以如果myDirective的模板是<div>before</div><div ng-transclude></div><div>after</div> 它将呈现之前的指令性内容。

这是全部。 我的问题是有可能以某种方式将更多的单个HTML块传递给我的指令?

例如

假设指令的使用应该是这样的:

<my-multipart-directive> 
    <part1>content1</part1> 
    <part2>content2</part2> 
</my-multipart-directive> 

,并有一个模板:

<div> 
    this: <div ng-transclude="part2"></div> 
    was after that: <div ng-transclude="part1"></div> 
    but now they are switched 
<div> 

呈现为

<div> 
    this: <div ng-transclude="part2">content2</div> 
    was after that: <div ng-transclude="part1">content1</div> 
    but now they are switched 
<div> 

(心里对自己说)我能以某种方式在节点的HTML值绑定到模型,使我能够以这样的方式来使用它,而把它称为“transclude” ......

感谢

+0

虽然我已经接受hassassin的回答相当长的一段前。 看起来,正确和最新的做法即将改变。见凯维纽斯的答案。 – epeleg

回答

30

启动角度1.5,它现在可以创建多个插槽。相反transclude的:真正,你提供一个对象与每个插槽的映射:

https://docs.angularjs.org/api/ng/directive/ngTransclude

angular.module('multiSlotTranscludeExample', []) 
.directive('pane', function(){ 
    return { 
     restrict: 'E', 
     transclude: { 
     'title': '?pane-title', 
     'body': 'pane-body', 
     'footer': '?pane-footer' 
     }, 
     template: '<div style="border: 1px solid black;">' + 
        '<div class="title" ng-transclude="title">Fallback Title</div>' + 
        '<div ng-transclude="body"></div>' + 
        '<div class="footer" ng-transclude="footer">Fallback Footer</div>' + 
       '</div>' 
    }; 
}) 
+0

不错,它们使用我上面提到的语法几乎如此。 太糟糕了,他们没有更新transclude的文档https://docs.angularjs.org/api/ng/service/$compile。 我也不确定我了解transclude对象属性的命名约定,以及它们与指令模板的HTML元素以及使用该指令的HTML元素之间的关系。 – epeleg

+0

它看起来像对象是归一化被转移元素标记名称(即标准化为paneTitle的)与指令模板元素的ng-transclude属性的值之间的映射。 – epeleg

+0

恕我直言,这是违反直觉的,我希望它能以与范围相似的方式反过来:{}即模板的解析值将在左边,值将给出指令从哪里得到它。 – epeleg

21

很酷的问题。我不确定是否有内置的方式,但您可以通过非常通用的方式自行完成。

您可以通过在$ transclude服务通过这样的访问transcluded元素:

$transclude(function(clone, $scope) { 

如果克隆将成为联预transcluded内容的副本。然后,如果你的标签这样的元素内容:

<div id="content"> 
     <div id="content0">{{text}}</div> 
     <div id="content1">{{title}}</div> 
    </div> 

你也可以遍历的内容和编译如下:

$scope.transcludes.push($compile(clone[1].children[i])($scope)); 

太好了!现在你只需要放置在正确的位置的内容在你的模板

 '<div id="transclude0"></div>' + 
    '<div id="transclude1"></div>' + 

然后你就可以在你的链接功能分配正确

angular.element(document.querySelector('#transclude' + i)).append(scope.transcludes[i]); 

我成立了一个fiddle你可以与播放内容有这个设置。

希望这有助于!

+1

谢谢。这看起来非常接近我的想法。 我不确定我了解$ transclude服务实际做了什么,但我想我可以在文档中阅读它。为什么你选择将“div#content”作为“div#content0”和“div#content1”的包装,如果内容不包含它们,会发生什么变化?还有'clone'参数究竟是什么? (如果克隆[1]'是'div#content',什么是clone [0]?) – epeleg

+0

好吧...我去了文档,没有找到任何对$ transclude的引用...你在哪里找到它以及如何使用它? – epeleg

+0

你可以在transclude指令中看到它https://github.com/angular/angular.js/blob/481508d0e7ae9e4984ea380b9a43e589551c7a5b/src/ng/directive/ngTransclude.js它在这里定义:https://github.com/angular /angular.js/blob/27873acbf0003031be52c719d068e46e4f7ef31f/src/ng/compile.js#L1541并在此处描述:https://github.com/angular/angular.js/blob/27873acbf0003031be52c719d068e46e4f7ef31f/src/ng/compile.js#L326 – hassassin

1

在我们的项目中,我们已经对JSF 2的UI之后的多站点trasclusion进行建模:组合,ui:insert,ui:define(请参阅ui:composition)。

实现包含三个简单指令:ui-template,ui-insert,ui-define(请参阅angularjs-api/template/ui-lib.js)。

定义模板一个写下面的标记(见angularjs-api/template/my-page.html):

<table ui-template> 
    <tr> 
    <td ui-insert="menu"></td> 
    </tr> 
    <tr> 
    <td ui-insert="content"></td> 
    </tr> 
</table> 

,并宣布了一项指令(见angularjs-api/template/my-page.js):

var myPage = 
    { 
    templateUrl: "my-page.html", 
    transclude: true 
    }; 

    angular.module("app"). 
    directive("myPage", function() { return myPage; }); 

最后,以实例化指令一个需求(见angularjs-api/template/sample.html):

<my-page> 
    <div ui-define="content"> 
    My content 
    </div> 
    <div ui-define="menu"> 
    <a href="#file">File</a> 
    <a href="#edit">Edit</a> 
    <a href="#view">View</a> 
    </div> 
</my-page> 

工作样品可以通过rawgit可以看出:sample.html

参见:Multisite Transclusion in AngularJS

相关问题