IME確定前の入力内容をngModelで取得する
ngModelはIME入力確定後に入力内容が変数に反映される。確定前の「はてn」みたいな入力途中の内容は取得できない。
確定前の内容も反映したいときに、上記のようなDirectiveを作るのもありだが、Angular1.3からngModelOptionsが導入され、updateOnでngModelの更新イベントを指定できるようになったので、
<!-- inputイベント発生時にngModelを更新する --> <input type="text" ng-model="text" ng-model-options="{ 'updateOn': 'input' }">
これで簡単にできる!、、、かと思いきや、上記でも確定後更新となってしまう。。
バグかなーと思いソースを読むとこのあたりでIME入力開始〜確定(compositionstartイベントからcompositionendイベントまで)まで更新をストップする処理が書かれている。1.2.2から導入されていて、意図はここに書いていた。
ngModelは(かなり大まかにだけど。。。)、①inputイベントで入力内容を監視、一時的に内部の変数に保持し、②updateOnで指定されているイベント発生、③ngModelで指定されている変数にその内部変数の値をコピーする、という流れになっていて、「一時的に内部の変数に保持」のところがそもそも更新されていないのでupdateOnで指定しても動作しない。
Directiveを使わない解決方法
下記のように特定のinputだけ、compositionstartイベントとcompositionendイベントをstopImmediatePropagationでストップすれば、Directiveを作らずに問題を解決できるのでおすすめや!!
<!doctype html> <body ng-app="App"> <p>{{ text }}</p> <input type="text" ng-model="text" class="disabled-composition-events"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script> <script> angular.module('App', []) .run(function () { // compositionstart, compositionendをストップする angular .element('.disabled-composition-events') .on('compositionstart compositionend', function (e) { e.stopImmediatePropagation(); }); }); </script> </body>