Angularjs:値の変更中にinput [text] ngChangeが発生します


92

ngChangeは、値が変化しているときに発生します(ngChangeは、従来のonChangeイベントに似ていません)。クラシックなonChangeイベントをangularjsにバインドするにはどうすればよいですか?

現在のバインディング:

<input type="text" ng-model="name" ng-change="update()" />

同様の何かを探しているだけで、フィールドが有効な場合にのみ更新を検討することもできます。そうすることで、ユーザーは入力を有効な形式に変換するのに苦労することができます(または、プロンプトやフィルターを使用してユーザーを支援することができます)。正しく取得したら、更新で報酬を与えることができます!
スティーブブラック

使用にイベントを指定することができます(ただぼかしていない)、その他の特性は非常にすぐの角に組み込まれるべきはるかに柔軟なソリューション:github.com/angular/angular.js/pull/2129
wired_in

回答:


96

この投稿は、blurイベントが発生するまでモデルの入力への変更を遅らせるディレクティブの例を示しています。

これは、新しいng-model-on-blurディレクティブでng-changeが機能することを示すフィドルです。これは元のフィドルを少し調整したものです。

ディレクティブをコードに追加する場合は、バインディングを次のように変更します。

<input type="text" ng-model="name" ng-model-onblur ng-change="update()" />

ここにディレクティブがあります:

// override the default input to update on blur
angular.module('app', []).directive('ngModelOnblur', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        priority: 1, // needed for angular 1.2.x
        link: function(scope, elm, attr, ngModelCtrl) {
            if (attr.type === 'radio' || attr.type === 'checkbox') return;

            elm.unbind('input').unbind('keydown').unbind('change');
            elm.bind('blur', function() {
                scope.$apply(function() {
                    ngModelCtrl.$setViewValue(elm.val());
                });         
            });
        }
    };
});

注:@wjinが以下のコメントで言及しているように、この機能はAngular 1.3(現在ベータ版)で直接サポートされていngModelOptionsます。詳しくはドキュメントをご覧ください。


1
elm.unbind( 'input')はInternet Explorer 8で「TypeError」をスローするため、他のバインド解除ステートメントはまったく実行されません。elm.unbind( 'input')を別の行に移動し、try / catchブロックで囲んで解決しました。
Rob Juurlink 2013

1
Angular 1.2にはng-blurディレクティブがあります:docs.angularjs.org/api/ng.directive
JJ Zabkar

5
このコードを機能させましたが、ディレクティブの優先度(つまり、優先度:100)を設定する必要がありました。Angular 1.2.10を使用しています。私の推測では、ngModelOnblurディレクティブはngModelディレクティブの前に実行されていたため、まだバインドを解除するものはありませんでした。:また、このページでは、将来的には、このためのソリューションであり内蔵されていてもよいように、それが思われてしまうgithub.com/angular/angular.js/pull/1783
アラン・西

4
注少なくとも角度1.3では、この機能は、ドキュメントng-model-options="{ updateOn: 'default blur' }"参照してデフォルトの実装でサポートされています
wjin

2
@RobJuurlink(または「input」にバインドまたはアンバインドしようとしたときにIE8の「TypeError」に遭遇した人)-Angularのソースを見ると$sniffer、ブラウザが「input」をサポートしているかどうかを判断するために使用されていることがわかります。彼らは「キーダウン」にフォールバックします。場合にのみ、アンバインド「入力」に上記のディレクティブを更新した場合$sniffer.hasEvent('input')、あなたはそのエラーを回避することができ、まだIE8での作業-リターンが真
bvaughn

32

これは、AngularJSに最近追加されたものであり、将来の回答として機能します(また、 別の質問についても)。

(現在ベータ版1.3で)角度の新しいバージョンは、AngularJSはネイティブに使用して、このオプションをサポートしていますngModelOptionsように、

ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }"

NgModelOptionsのドキュメント

例:

<input type="text" name="username"
       ng-model="user.name"
       ng-model-options="{updateOn: 'default blur', debounce: {default: 500, blur: 0} }" />

1.3ベータ5では正しく機能しませんが、現在のマスタービルド2602で修正されています
manikanta

そして、それがまだベータ版であり、私が現在作成しているような「現実の」アプリケーションでは使用できない理由です。
reaper_unique 2014

これはAngular 1.2.xのモジュールのようなng-model-optionsです。github.com/fergaldoyle/modelOptions
Fergal

8

追加の「Enter」キープレスサポートを探している人がいる場合のために、Gloppyが提供するフィドルのアップデートを以下に示します。

キープレスバインディングのコード:

elm.bind("keydown keypress", function(event) {
    if (event.which === 13) {
        scope.$apply(function() {
            ngModelCtrl.$setViewValue(elm.val());
        });
    }
});

5

IE8で苦労している人(unbind( 'input')が気に入らない人)のために、私はそれを回避する方法を見つけました。

$ snifferをディレクティブに挿入して使用します。

if($sniffer.hasEvent('input')){
    elm.unbind('input');
}

IE8はこれを行うと落ち着きます:)


または、try / catchを使用してください
Wired_in

4

私の知識によると、selectオプションでng-changeを使用し、テキストボックスの場合はng-blurを使用する必要があります。


これが正解です。当時、質問されたときは明らかに存在しませんでした。
ダウンハンド2015年

ありがとうございました...これが答えになるはずです
Renjith


0

デフォルトの入力のonChange動作をオーバーライドします(コントロールの損失フォーカスと値が変更された場合のみ関数を呼び出します)

注:ngChangeは、値が変更されているときにイベントを発生させる従来のonChangeイベントとは異なります。このディレクティブは、フォーカスを取得したときに要素の値を保存します。
Onは、新しい値が変更されたかどうかをチェックし、変化した場合はイベントを発生させます。

@param {String}-「onChange」を起動する必要があるときに呼び出される関数名

@example <input my-on-change = "myFunc" ng-model = "model">

angular.module('app', []).directive('myOnChange', function () { 
    return {
        restrict: 'A',
        require: 'ngModel',
        scope: {
            myOnChange: '='
        },
        link: function (scope, elm, attr) {
            if (attr.type === 'radio' || attr.type === 'checkbox') {
                return;
            }
            // store value when get focus
            elm.bind('focus', function () {
                scope.value = elm.val();

            });

            // execute the event when loose focus and value was change
            elm.bind('blur', function () {
                var currentValue = elm.val();
                if (scope.value !== currentValue) {
                    if (scope.myOnChange) {
                        scope.myOnChange();
                    }
                }
            });
        }
    };
});

0

私はまったく同じ問題を抱えていましたが、これでうまくいきました。追加ng-model-updateしてng-keyup、準備完了です。ここにドキュメントがあります

 <input type="text" name="userName"
         ng-model="user.name"
         ng-change="update()"
         ng-model-options="{ updateOn: 'blur' }"
         ng-keyup="cancel($event)" />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.