web-dev-qa-db-ja.com

カスタムディレクティブと組み合わせたng-repeat

Ng-repeatディレクティブを独自のカスタムディレクティブと組み合わせて使用​​すると問題が発生します。

HTML:

<div ng-app="myApp">
  <x-template-field x-ng-repeat="field in ['title', 'body']" />
</div>

JS:

angular.module('myApp', [])
    .directive('templateField', function () {
        return {
            restrict: 'E',
            compile: function(element, attrs, transcludeFn) {
                element.replaceWith('<input type="text" />');
            }
        };
    });

jSFiddle を参照してください

ここでの問題は、何も置き換えられないことです。私が達成しようとしているのは、2x入力フィールドの出力であり、 'x-template-field'タグがDOMで完全に置き換えられています。私の疑惑は、ng-repeatが同時にDOMを変更しているため、これは機能しないということです。

this Stack Overflowの質問によると、受け入れられた回答は、これが以前のバージョンのAngularJS(?)で実際に機能したことを示しているようです。

Element.html( '...')は機能しませんか?

Element.html( '...')は実際に生成されたHTMLをターゲット要素に挿入しますが、テンプレートタグの子要素としてHTMLを使用するのではなく、DOMで完全に置き換えます。

テンプレートタグをng-repeatディレクティブを持つ別のタグでラップしないのはなぜですか?

基本的に、上記と同じ理由で、生成されたHTMLを繰り返しタグの子要素として使用したくありません。私のアプリケーションではおそらく適切に機能しますが、マークアップをAngularに合わせて調整したように感じますが、その逆ではありません。

'template'プロパティを使用しないのはなぜですか?

'template'/'templateUrl'プロパティから取得したHTMLを変更する方法が見つかりませんでした。挿入したいHTMLは静的ではなく、外部データから動的に生成されます。

私は自分のマークアップにうるさいですか?

恐らく。 :-)

どんな助けでも大歓迎です。

18
vrutberg

ディレクティブは、より高い優先度を使用してng-repeatの前に実行する必要があるため、ng-repeatが要素を複製すると、変更を選択できます。

ディレクティブユーザーガイド の「コンパイル/リンク分離の背後にある理由」のセクションには、 ng-repeatのしくみ。

current ng-repeat priority は1000なので、これより高い値で実行できます。

したがって、コードは次のようになります。

angular.module('myApp', [])
    .directive('templateField', function () {
        return {
            restrict: 'E',
            priority: 1001, <-- PRIORITY
            compile: function(element, attrs, transcludeFn) {
                element.replaceWith('<input type="text" />');
            }
        };
});
16
rgarcia

あなたのng-repeatテンプレート内。要素の属性を変更し、それに応じてディレクティブを変更して、ng-repeatが必要かどうか、またはディレクティブのコンパイル内で使用するデータを決定できます。

HTML(属性):

<div ng-app="myApp" template-field></div>

JS:

angular.module('myApp', [])
    .directive('templateField', function () {
        return {          
            restrict: 'A',
            template:'<input type="text" value="{{field}" ng-repeat="field in [\'title\',\'body\']" />'            
        };
    });

デモ: http://jsfiddle.net/GDfxd/3/

要素としても機能します:

HTML(要素):

<div ng-app="myApp" >
    <template-field/>
</div>

JS

angular.module('myApp', [])
    .directive('templateField', function () {
        return {          
            restrict: 'E',
            replace:true,
            template:'<input type="text" value="{{field}}" ng-repeat="field in [\'title\',\'body\']" />'

        };
    });

デモ: http://jsfiddle.net/GDfxd/3/

3
charlietfl