2016-12-02 7 views
1

this example私はng-eachの中にトランスコードされた命令を持っています。それは、それぞれの最後のパスに移籍だけを含めるようだ!それぞれのコードベースのコードは、最後の要素では機能しません。

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>要素の作成はCSSのパターンを破るを動作しますが、テンプレート自体に<ng-transclude>を使用した場合

  • を注意すべきいくつかのことinput:invalid+.label私は両方の私のアプリ htmlの両方の方法に根本的と考えている働くこと。
  • ng-transclude属性も同様に動作しますが、これは間違いなくng-eachとは何かを持っている私のspan.label
  • を一掃するからです。 3つのli要素を手動で作成し、$ctrl.sources[0]$ctrl.sources[1]などにリンクすると、うまく動作します。

何が起こっているのですか?

答えて

1

このように動作するように設計されていません。 <li>と<というラベルの付いた要素>(<の本文は>)の2つの例外が発生しています。

基本的にNGリピートの各反復は、最後<標識要素>トランスクルーが表示された理由である前<標識要素>トランスクルー、上踏みされます。

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

恐ろしい神様...今、私たちは手動ですべての情報の更新を処理しなければなりません(コンテンツが変更された場合でも何が起こるか)。それは驚くほど無益です。再利用可能なコンポーネントを作成すると、 'ng-each'の内部で使用されるかどうかを制御することができないので、実際にはtranscludeを使用しないでください! –

+0

また、私が理解していないのはなぜですか?バグは、あなたがマークアップでtranscludeするときではなく、リンク関数で 'transclude()'を実行したときにのみなぜ現れますか? –

+0

ここには、ng-repeatの動作に関する記事があります。http://liamkaufman.com/blog/2013/05/13/understanding-angularjs-directives-part1-ng-repeat-and-compile/ – RamblinRose

関連する問題