web-dev-qa-db-ja.com

ユーザーが入力を完了したときにのみanglejs ngChangeハンドラーが呼び出されるようにする方法

inputフィールドを使用して、ngChangeのバリアントを適用します。

inputフィールドはajax呼び出しとのバインドの一種です。ユーザーが入力を変更すると、サーバー側がデータを処理しますが、あまり頻繁に呼び出しを行いたくありません。

ユーザーが本当に文字列を入力したい場合、ユーザーが入力しようとしているWordを終了した後にのみ呼び出しが行われるようにします。それにもかかわらず、ぼかしなどのイベントは使いたくありません。 setTimeoutではなく、これを実装するより良い方法は何でしょうか?

49
9blue

Angular> 1.3でng-model-optionsを使用

 <input type="text"
         ng-model="vm.searchTerm"
         ng-change="vm.search(vm.searchTerm)"
         ng-model-options="{debounce: 750}" />

ng-model-optionsなし-マークアップ内:

<input ng-change="inputChanged()">

バッキングコントローラー/スコープ内

var inputChangedPromise;
$scope.inputChanged = function(){
    if(inputChangedPromise){
        $timeout.cancel(inputChangedPromise);
    }
    inputChangedPromise = $timeout(taskToDo,1000);
}

その後、taskToDoは変更なしで1000ミリ秒後にのみ実行されます。

105
calebboyd

Angular 1.3の場合、Angular ng-model-optionsディレクティブを使用できます

<input ng-change="inputChanged()" ng-model-options="{debounce:1000}">

ソース: https://stackoverflow.com/a/26356084/1397994

38
Adrien

独自のディレクティブを作成します-これは、設定した条件に基づいてmyTextでのみコマンドを実行します

<input my-change-directive type="text ng-model="myText" />

.directive('myChangeDirective',function() {
    return {
        require : 'ngModel',
        link : function($scope,$element,$attrs) {
            var stringTest = function(_string) {
                //test string here, return true
                //if you want to process it
            }
            $element.bind('change',function(e) { 
                if(stringTest($attrs.ngModel) === true) {
                    //make ajax call here
                    //run $scope.$apply() in ajax callback if scope is changed
                }
            });
        }
    }
})
1
koolunix