2016-06-02 3 views
0

私のコントローラには、ディレクティブを作成するためにng-repeatが使用するリストがあります。私のディレクティブでは、ディレクティブの要素に追加するためにtransclusionを使用します。AngularJS:ディレクティブに含まれるコンテンツは消えます。

私のリストに最初のアイテムを追加すると、期待どおりに動作するようですが、2番目のアイテムを追加すると、最初のアイテムの要素から継承されたコンテンツが消えます。これは私には意味がないので、私が誤解しているものがなければなりません。

私はこの問題を再現したexampleを作成しました。

最初の項目が追加された後に予想されるように、HTMLはなります

<div ng-controller="ctrl as c" class="ng-scope"> 
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope"> 
     <div class="ng-binding">1</div> 
     <span class="ng-scope">Transcluded</span> 
    </test> 
</div> 

2番目の項目が追加された後、トランスクルードコンテンツは最初の項目の要素でなくなりました!

<div ng-controller="ctrl as c" class="ng-scope"> 
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope"> 
     <div class="ng-binding">1</div> 
    </test> 
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope"> 
     <div class="ng-binding">2</div> 
     <span class="ng-scope">Transcluded</span> 
    </test> 
</div> 

HTML:

<div ng-app="ui"> 
    <div ng-controller="ctrl as c"> 
    <test ng-repeat="item in c.items track by $index" item="item">Transcluded</test> 
    </div> 
</div> 

活字体:

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

class Controller { 
    public items = []; 

    constructor($timeout) { 
    $timeout(() => this.items.push({Id: 1}), 1000); 
    $timeout(() => this.items.push({Id: 2}), 2000); 
    } 
} 
app.controller('ctrl', ['$timeout', Controller] 

app.directive('test', function($compile) { 
    return { 
    scope: { 
     item: '=' 
    }, 
    transclude: true, 
    template: "<div>{{item.Id}}</div>" 
    link: function(scope, element, attrs, controller, transcludeFn) { 
     console.log("Appending transcluded content to " + scope.item.Id) 
     let e = transcludeFn(); 
     element.append(e); 
    } 
    }; 
}); 

JSFiddle:https://jsfiddle.net/rmytw9cr/2/

+0

利用NG-transclude属性は、それがより多くの情報のために...作業を開始する可能性があるhttp://teropa.info/blog/2015/06/09/transclusion.html – Ajay

答えて

1

あなたはtransclude機能を使用する必要がある場合を除き、上の(チェックアウトtransclutionを、それを使用しないでくださいGoogleの詳細については、それは少し複雑です、例えば、あなたは、継承されたpをコンパイルすることができますあなたの選択の範囲を持つアート)。

単純なトランスクリプションでは、transcludeディレクティブを使用できます。

は、次のテンプレートを試してみてください、そして、あなたのディレクティブからtranscludeを削除:

template: "<div><div>{{item.Id}}</div><div ng-transclude></div></div>" 

アップデート: トランスクルー機能を使用するには、あなたはそれがどのように動作するかを理解する必要があります。 transclusion関数は、最初の引数としてコールバックを取得します。コールバック関数は、第1引数としてトランスコードされたhtml要素を取得します。

ので、それを使用するための適切な方法、次のようになります。

transcludeFn(function(compiledHtml) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
}); 

トランスクルー機能もでHTMLをコンパイルする範囲である別の引数を取得することができます。その場合は、あなたが最初の引数、および第二のようにコンパイルされたHTMLとコールバックとしてスコープを供給する必要があります

transcludeFn(someScope, function(compiledHtml) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
}); 

と最終のために - コールバックはまた、トランスクルードである二番目の引数を、取得することができますスコープ:テストディレクティブで

transcludeFn(someScope, function(compiledHtml, transScope) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
    // Here transScope will be the same as someScope 
}); 

transcludeFn(function(compiledHtml, transScope) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
    // Here transScope will be the same as directive scope 
}); 
+0

を参照してください。ありがとうそれは私の問題を解決します。しかし、なぜ私が試したようにうまくいかなかったのか不思議です。 – meum

+0

これは、トランジション機能の働きによるものです。 transclusion関数を呼び出すと、最初の引数としてコールバックを指定します。このコールバックでは、最初の引数がtranscluded要素です。私の答えを例で更新する –

+0

答えに更新を加えました –

関連する問題