AngularJSのバリデーションにハマった件をまとめてみた。その1
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。
今回の案件ではAngularJSのFormのバリデーションを用いました。
チェックの条件をView側に埋め込むことができ、
また、ngMessage ディレクティブを用いることで、エラーメッセージの表示まで行うことができます。
非常に便利な機能ではあるのですが、2点ほどハマった点があったので紹介します。
Modelにバインディングされていない
冷静に考えればそのとおりなのですが、バリデーションでエラーとなった値はModelにはバインディングされません。
これを意識しておかないとパスワードとパスワード(再入力)の同値評価をバリデーションで行おうとした際に、 ちょっと困ったことになります。
現象説明
上記はパスワードとパスワード確認用を入力するフォームです。
両方のフォームにバリデーションに引っかからない値を入れる分には評価も正しく行われます。
しかし、バリデーションに引っかかる値を入れた時の挙動に注意が必要です。
この状態でパスワード確認の項目に対して、同一の8文字以下の文言を入れてみます。
同一の文字を入れているはずが、$scope.passsword === $scope.passwordConfirmの値がfalseになっています。
これは、passwordに対するバリデーションが失敗しているため、model側に値が代入されておらず、
代入されていないmodelとの比較を行っているため、同値評価の結果がfalseとなっています。
この値をValidation結果として用いてしまうと、
同一の値を入れたはずが、同一の値が入っていないといったエラメッセージが表示されるといった現象が発生します。
解決策
サンプルには、$scope.myForm.password.$viewValueと$scope.passwordConfirmの
同値評価も行っています。
こちらは、バリデーションに引っかかるような値を入れている場合も正しく評価されています。
$viewValueはその名の通り、現在のviewに反映されている値となります。
このようにバリデーションの伴う入力を行う場合、実際に入力された値を参照するのか、
それともモデルにバインディングされた値を参照するのかで挙動が異なるケースがあるので注意が必要です。
最後に
今回の注意点を反映させたパスワードフォームの例を下記においておきます。
なお、バリデーション用のディレクティブはアシアルブログ様の例をそのまま使わせて頂きました。