web-dev-qa-db-ja.com

フォーム全体のngChangeのような機能

入力フィールドの1つに変更があるたびに、フォーム全体に対してng-changeと同等の処理を行いたいと思います。

AngularJS 1.3以降、デバウンスオプションがありますが、単一の入力にのみ適用されることを知っています。

フォーム全体に適用される「デバウンス」/「変更時」機能を探しています。

38
chenop

フォームにng-changeを実行する組み込みの方法はありません。

ビューモデルを適切に構成した場合、フォーム入力は特定のスコープに公開されたプロパティにバインドされる可能性が高いため、必要さえありません。

$scope.formData = {};

ビューで:

<form name="form1">
  <input ng-model="formData.a">
  <input ng-model="formData.b">
</form>

次に、モデルの変更を($watchで)詳細に監視します(必要な要素にデバウンスオプションを適用します)。

$scope.$watch("formData", function(){
  console.log("something has changed");
}, true);

そして、問題は、もちろん、これはディープウォッチであり、高価であるということです。また、フォームの変更だけでなく、任意のソースからのformDataの変更にも反応します。

したがって、別の方法として、フォームを補完し、フォームの変更イベントに反応する独自のディレクティブを作成できます。

.directive("formOnChange", function($parse){
  return {
    require: "form",
    link: function(scope, element, attrs){
       var cb = $parse(attrs.formOnChange);
       element.on("change", function(){
          cb(scope);
       });
    }
  }
});

使用法は次のとおりです。

<form name="form1" form-on-change="doSomething()">
  <input ng-model="formData.a">
  <input ng-model="formData.b">
</form>

plunker 説明用。

「変更」イベントは、 jQuery documentation: のように、テキスト入力のぼかしでのみ発生することに注意してください。

changeイベントは、値が変更されると要素に送信されます。このイベントは、<input>要素、<textarea>ボックス、および<select>要素に制限されています。選択ボックス、チェックボックス、ラジオボタンの場合、ユーザーがマウスで選択するとすぐにイベントが発生しますが、他の要素タイプの場合、要素がフォーカスを失うまでイベントは延期されます。

57
New Dev

これを行う「ハッキング」方法の1つは、ウォッチャーをダーティなフォームに設定することです。これは、要件に応じて有効で、次のようなことができます。

   $scope.$watch('form.$dirty',function(v){
         if(!v){return}
         form.$setPristine()
         /*do something here*/
    })

あなたができる有効な変更されたフォームでのみコードを実行したい場合、これはフォームが変更されるたびに実行されます

       if(!v || form.$invalid){return}

そして、フォームが$ valid状態になったときにのみコードを実行したい場合は、ウォッチャーを 'form。$ valid'に設定するだけです。

ウォッチャーでスコープを汚染したくない場合は、変更時のapiイベントを公開し、ウォッチャーを内部で処理するフォームの周りにいつでもディレクティブを作成できます

8

Eric Soykeのコメントによると、キーアップイベントでフォームの変更のチェックをフックできます。

この方法では、組み込みディレクティブng-keyupを単純に使用できます。

<form name="form1" ng-keyup="doSomething()">
7
Lorenzo Meriggi

さて、スーパースーパーレイト答え...しかし、これはかなりきちんと動作します

// html
<form name="$ctrl.form">...</form>

// controller
function $postLink() {
    ctrl.form.$$element.on('change', function () {
        console.log('fired');
    });
}
1
Eydrian