2016-12-02 22 views
1

工作在this example我有一個ng-each內部的transcluded指令。它似乎只包括通過每個最後一遍的transclusion!基於代碼的transclude沒有爲最後一個元素

var app = angular.module('testApp', []); 
 

 
app.directive ('labeledElement', [ 
 
() => { 
 
\t const link = ($scope, $el, attrs, _0, transclude) => { 
 
\t \t $scope.label = attrs.label; 
 
\t \t $el.find('label').prepend(transclude()); 
 
\t } 
 
\t return { 
 
\t \t restrict: 'E', 
 
\t \t link, 
 
\t \t scope: { 
 
\t \t \t label: '@', 
 
\t \t }, 
 
\t \t transclude: true, 
 
\t \t template: ` 
 
<label> 
 
\t <span class="label">{{label}}</span> 
 
</label> 
 
`, 
 
\t } 
 
}]) 
 

 
app 
 
.controller('TopLevel', 
 
\t function() { 
 
\t \t this.sources = [ 
 
\t \t \t { domain:"first item"}, 
 
\t \t \t { domain:"second item"}, 
 
\t \t \t { domain:"third item"}, 
 
\t \t ] 
 
\t }) 
 

 
angular.bootstrap (document.querySelector('body'), ['testApp'])
<body ng-controller="TopLevel as $ctrl"> 
 
    <style> 
 
     input:invalid+.label { 
 
     color: red; 
 
     } 
 
    </style> 
 
    <p>Why on earth does only the last input display?</p> 
 
\t <section class="admin-integration-sources"> 
 
\t \t <div> 
 
\t \t \t <ul class="configured-sources-list"> 
 
\t \t \t \t <li ng-repeat="source in $ctrl.sources"> 
 
\t \t \t \t \t <labeled-element label="A Label"> 
 
\t \t \t \t \t \t <input ng-model="source.domain" required /> 
 
\t \t \t \t \t </labeled-element> 
 
\t \t \t \t </li> 
 
\t \t \t </ul> 
 
\t \t </div> 
 
\t </section> 
 
</body> 
 

 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>

有幾件事情需要注意

  • 如果我在自己工作的事情建立一箇中間<ng-transclude>元素的模板使用<ng-transclude>打破了CSS樣式input:invalid+.label,我認爲這兩個我的應用程序 html是如何意義工作。
  • ng-transclude作爲一個屬性的作品很好,但會消滅我span.label
  • 這肯定有事情做與ng-each。如果我手動創建三個li元素並將它們鏈接到$ctrl.sources[0]$ctrl.sources[1]等,它工作得很好!

這是怎麼回事!?

回答

1

Transclusion的設計目的不是這樣。你有兩個transclusions在同一範圍內發生的事情,<李>和<標記元素>,這是<體>的範圍。

本質納克重複的每次迭代被踩現有<標記的元件> transclusion,這就是爲什麼只有最後<標記的元件> transclusion出現。

Here's an expert explanation of the issue

的解決方案是使用編譯,因爲你需要它來修復標記。

app.directive('labeledElement', function() { 
    return { 
     restrict: "E", 
     compile: function (element, attr) { 
      let template = angular.element('<label><span class="label">' + element.attr('label') + '</span></label>'); 
      // Extract the children from this instance of the directive 
      let children = element.contents(); 
      // Wrap the children in our template 
      let injectElement = template.find('inject'); 
      injectElement.replaceWith(children); 
      // Append this new template to our compile element 
      element.append(template); 
     } 
    } 
}); 

這裏有一個plunkr使用編譯重現您的問題和解決方法。

+0

親愛的上帝太可怕了......現在我們必須手動處理每一條信息(什麼當內容改變時甚至會發生),這就是令人震驚的毫無價值的更新。他們實際上是說你不應該使用transclude,因爲如果你創建了一個可重用的組件,你不能控制它是否會被用在'ng-each'之內! –

+0

另外我不明白 - 爲什麼只有當你在鏈接函數中執行'transclude()'時,纔會顯示錯誤,而不是當你在標記中進行跨越時。 –

+0

這裏有一篇關於ng-repeat的工作原文http://liamkaufman.com/blog/2013/05/13/understanding-angularjs-directives-part1-ng-repeat-and-compile/ – RamblinRose

相關問題