2013-04-09 9 views
29

入力フィールドが無効とマークされているときに、いくつかのアクションを実行する必要のあるディレクティブを作成しようとしています。AngularJSディレクティブウォッチの妥当性

<input type="text" ng-model="primeNumber" validate-prime invalid-add-class="error"> 

検証プライム用途:この例では、私は入力が素数であるかどうかを確認するディレクティブを持っていると仮定し、私はそれが無効だときの要素にクラスを追加するディレクティブを作成することができますモデルの有効性を更新するためにng-model上のパーサとフォーマッタを使用します。

無効なadd-classディレクティブは、モデルが無効なときにクラス「エラー」を追加し、モデルが有効なときに削除するようにします。つまり、モデルコントローラの$ valid(または$ invalid)プロパティを監視する必要があります。しかし、私はどのようにこれを動作させるかを理解することはできません。私が試した:

link : function(scope, element, attrs, ctrl) { 
    ctrl.$watch("$valid", function(newVal, oldVal) { 
    //never fired 
    }); 
} 

おそらく、私は、スコープに、いくつかの変数を見ることができるが、私はを監視するためにどの変数かわかりません。

モデルの妥当性が変わったときにどうすれば通知できますか?あなたの入力に

+0

あなたの指示を分かち合うことができれば、それは素晴らしいことでしょう! –

+0

私はこれを正確に使用したことは覚えていませんが、CaioToOnの2番目の解決策はリンク機能全体が既にかなり機能していることです。有効性が変わったときに、あなたが望むどんなアクションでも、2番目の関数の本体だけを埋めなければなりません。 – Tiddo

答えて

60

あなたは<form>を持っている場合は、(「あるmyForm」を想定することができます)、それにnameを追加し、namemyInputとさせて頂きます)。あなたはformを持っていない場合、あなたは常に機能を見ることができ

scope.$watch('myForm.myInput.$valid', function(validity) {}) 

:あなたはで$watchこれにできるはずです。この方法:

scope.$watch(function() { return ctrl.$valid; }, function(validity){}); 

あなたは、フォームのアプローチhereについての詳細を読むことができます。

+1

あなたの2番目のアプローチは、私のためにそれをしました、ありがとう! – Tiddo

7

私たちの目標は、一般に、1つのフォームまたは入力とは独立して指令を作成することです。ローカルの$validプロパティを、特定の1つの書式の&入力名に強制的にバインドせずに読み込む方法を教えてください。

require: 'ngModel'をディレクティブ設定のプロパティの1つとして使用してください。これにより、リンク関数の第4引数としてローカルのngModelコントローラがインジェクトされます。$watchを直接$validに配置すると、ディレクティブの実装を特定のフォームまたは入力に結合する必要はありません。

require: 'ngModel', 
link: function postLink(scope, element, attrs, controller) { 
    scope.inputCtrl = controller; 
    scope.$watch('inputCtrl.$valid', handlerFunc) 
} 

ハンドラは、その構造体で$ validの変更を一貫して発生させる必要があります。 this Fiddleを参照してください。この入力は、米国郵便番号または郵便番号+ 4のパターンで検証されています。妥当性が変わるたびに警告が表示されます。

EDIT 3/21/14:この投稿は以前、実装問題の間違った原因に固執して私の妄想にぶち壊されました。私のせい。上記の例は、その固定を削除します。また、フィドルを追加すると、ウォッチ式の周りに引用符を追加すると、このアプローチが実際に動作することが示され、常に実行されます。

+0

これは本当ですか?なぜなら、 'inputCtrl。$ valid'は一度(リンク関数が実行されると)評価され、その結果が' scope。$ watch'に渡されるようです。したがって、実際の呼び出しは 'scope。$ watch(true、handlerFunc)'または 'scope。$ watch(false、handlerFunc)'であり、両方とも変数が監視されるわけではありません。 – Tiddo

+0

'inputCtrl。$ valid'はプリミティブな値ではなくオブジェクトのプロパティへの参照です。 '$ watch'が発生するたびに評価されます。私は個人的なプロジェクトに取り組んでいますが、現在は公開デモがありません。 – XML

+1

AFAIK 'inputCtrl。$ valid'はプリミティブです。 'true'、' false'、 'undefined'のいずれかです。これらはすべてプリミティブです。オブジェクトのプロパティへの参照を作成することはできません.Javascriptのオブジェクト自体に対してのみ参照できます。このJSFiddle:http://jsfiddle.net/9Mh92/2/も参照してください。ご覧のように、コードではコールバックがトリガーされず、引用符でのみコールされます。これは、プリミティブへの参照を作成できないためです。 'inputCtrl。$ valid'の前後に引用符を置くことで、現在のスコープでその式を評価するようにangleを指示するので、それは動作します。 – Tiddo

12

あなたは<form />を持っていない場合、あなたは簡単に1を得ることができます:あなたのディレクティブの定義では

require: '^form' 

してからリンク機能では、フォームを第四パラメータとして渡されます。

link: function (scope, element, attr, ctrl) { 

今、あなたは$ウォッチを実行するためにハードコードするフォームや入力フィールドを持っていない:

scope.$watch(ctrl.$name + '.' + element.attr('name') + '.$valid', 
function (validity) {}); 
+0

これは完璧でした。何らかの理由で私は 'ctrl [0]。$ name'を使用しなければなりませんでしたが、私のコントロールが1つのフォームの配列を返す理由はわかりません... – DoubleA

+1

'require'属性が配列を渡すと配列を返します(私はあなたのためだと思う) – pixelbits