7

私は AngularJS を使用してより大きなプロジェクトに取り組んでいます。そのため、1つのフォームの作業をできるだけ簡単にしたいと考えています。ブートストラップも使用しているため、フォーム内の単一の入力フィールドのコードは非常に冗長です。

<div class="control-group">
  <label class="control-label" for="inputEmail">Email</label>
  <div class="controls">
    <input type="text" id="inputEmail" placeholder="Email">
  </div>
</div>

次のような単一のタグを書くことができれば

<custom-input 
  label="Email" 
  name="inputEmail" 
  placeholder="Email" 
  type="text" 
  ... >
</custom-input>

代わりに、これはコードをクリーンに保ち、作業をシンプルにするのに役立ちます。

これを実現するために、カスタム AngularJS ディレクティブに取り組んでいます。私のディレクティブは現在、上記のブートストラップの例と同様のテンプレートを使用して、ラベルを入力タグに自動的に割り当てます。また、カスタム入力タグのカスタマイズを容易にするために、ディレクティブのコンパイラ関数はすべての属性をカスタム入力タグから実際の入力タグに移動します。

app.directive('customInput', function() {
    return {
      require: 'ngModel',
      restrict: 'E',
      template: '<div>' + 
                    '<label for="{{ name }}">the label</label>' +
                    '<input id="{{ name }}" ng-model="ngModel" />' +
                '</div>',
      scope: {
              ngModel: '=',
              name: '@name',
          },
      replace: true,
      compile: function (tElement, tAttrs, transclude) {
            var tInput = tElement.find('input');

            // Move the attributed given to 'custom-input'
            // to the real input field
            angular.forEach(tAttrs, function(value, key) {
                if (key.charAt(0) == '$')
                    return;
                tInput.attr(key, value);
                tInput.parent().removeAttr(key);
            });

            return;
        },
    };
});

スタック オーバーフローでは、カスタム入力フィールドの作成に関して多くの質問がありますが、それらはデータ バインディングカスタム フォーマット、またはng-repeat へのバインディングに関するものです。

ただし、私のアプローチには別の問題があります。データバインディングは正しく機能しますが、入力フィールドが「必須」の場合、Angular の統合フォーム検証モジュールが混乱します。何らかの理由で、検証は新しい入力フィールドを認識せず、空の値を持つデッドリファレンスのためにフォームを無効のままにします。最小限の例を参照してください。

デッドリファレンスはどこから来たのですか? 検証モジュールの参照を更新するにはどうすればよいですか? 全体的な目標を達成するためのより良い方法はありますか?

4

1 に答える 1

4
  1. ブール属性として、属性が移動された場合でも、div で依然として true である対応する必須プロパティがあります。
  2. 必要な属性が移動されていません。値がないため、スキップされているに違いありません。値なしでjavascriptを使用して要素に追加する方法さえわかりませんが、フォームrequired="required"修正を使用すると
  3. 使用transclude=trueすると、属性を移動したときにコンパイル フェーズの後に要素のコピーが使用されます。これにより、必要なプロパティが設定されないようになると思います。
  4. 何らかの理由でより高い優先度を割り当てる必要がありng-modelます。これは、 の名前が であるために div から削除されないためtattrsですngModel(ただし、div から削除しても優先度の必要性は削除されません)。

http://plnkr.co/edit/5bg8ewYSAr2ka9rH1pfE?p=preview

私がしたことは、required 属性を に変更し、required="required"次の 2 行をディレクティブ宣言に追加することだけでした。

  transclude: true,
  priority: 10,

ちなみに、テンプレート ラベルを付けng-transcludeたので、要素の内容がラベルに表示され、そのための属性を持つ必要はありません。

于 2013-06-15T08:43:00.980 に答える