M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

AngularJSのイベントリスナとモデルの値取得で地味にハマる

AngularJSで画面側をつくっていたところ、イベントリスナとモデルの値取得に関連するコードで地味にハマりました。ようするにこういうことです:

ng-minlength属性で最小文字数を指定されている<input type="text" ng-model="(任意のモデル名)">タグにバインドされたモデルの値は、このフォームの入力内容が指定された文字数を下回るとundefinedになる。よってバインドされたモデルの値にイベントリスナのJavaScriptコードからアクセスする場合はundefinedチェックが必要になる。

ng-change属性やng-blur属性でイベントリスナ(を実行する式)を指定してイベント発生時の処理をコードしていたのですが、入力値の文字数が少ないときになぜだかundefinedエラーが起きる現象に気が付きました。

はじめAngularJSによる双方向バインディングが非同期に行われることにより、イベントリスナ起動時点でモデルの値が未設定になってしまうことが起きるのかもと推測していたのですが、$scope.$apply()に関するインターネット上の記事をみるとそんなことはないはず、つまりバインディングとイベントリスナ(正確に言えばng-change属性やng-blur属性で指定された式の実行)は同期されています。

あれこれ試した末に上記のng-minlength属性が原因とわかりました。わかってみるとなるほどという挙動です。わざわざその入力欄の最小文字数を明確に定義しているわけですから、それを下回る値が設定されたらそこに関連付けされているモデルの値はundefined、つまり未設定・未初期化を示す値になるわけです。