2014-02-27 47 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

相關問題