92

値が変化している間に ngChange が発生します (ngChange は従来の onChange イベントとは異なります)。コンテンツがコミットされたときにのみ起動する古典的な onChange イベントを angularjs にバインドするにはどうすればよいですか?

現在のバインディング:

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

8 に答える 8

99

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

これは、新しい ng-model-on- blurディレクティブで動作する ng-change を示すフィドルです。これは元の fiddleを少し調整したものであることに注意してください。

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

<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ます。詳細については、ドキュメントを参照してください。

于 2012-08-08T17:55:14.300 に答える
33

これは、AngularJS への最近の追加に関するものであり、将来の回答として役立ちます (別の質問に対しても)。

Angular の新しいバージョン (現在は 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} }" />
于 2014-04-13T16:59:54.460 に答える
8

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

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

elm.bind("keydown keypress", function(event) {
    if (event.which === 13) {
        scope.$apply(function() {
            ngModelCtrl.$setViewValue(elm.val());
        });
    }
});
于 2012-10-20T03:47:06.107 に答える
5

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

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

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

これをするとIE8が落ち着きます:)

于 2013-01-02T04:29:05.020 に答える
3

スコープ変数の変更をよりよく反映するために $scope.$watch を使用していませんか?

于 2014-01-14T09:58:49.763 に答える
0

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

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

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

@example < 入力 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();
                    }
                }
            });
        }
    };
});
于 2013-12-25T11:49:15.340 に答える