Функция вызова с задержкой при изменении текстового поля в AngularJS
Не может показаться, что Google сделал пример того, как это делается.
Я успешно создал текстовое поле, которое вызывает функцию каждый раз, когда она изменяется. То, что я хотел бы сделать, это вызвать функцию только тогда, когда пользователь прекратил печатать за миллисекунды.
Я знаю, как это сделать в JQuery, используя событие keyup, и, вероятно, может заставить его работать таким образом, но вы хотите сделать это "путь Angular".
Edit
Возможно, это было не ясно из тега или текста, но я использую AngularJS и хочу использовать правильную методологию для этой структуры для создания этой функции задержки.
Ответы
Ответ 1
Для подхода angular можно ввести $timeout
в контроллер как зависимость и использовать $watch
для переменной области, которую вы назначили в ng-model
.
var timer=false;
$scope.ModelName='foo';
$scope.$watch('ModelName', function(){
if(timer){
$timeout.cancel(timer)
}
timer= $timeout(function(){
/* run code*/
},delay)
});
Ответ 2
Для этого существует ng-model-options
<input id="delayedModel" ng-model="delayedModel" ng-change="callDelayed()" ng-model-options="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }" />
метод callDelayed
вызывает только 500 мс после ввода последнего char или размытия
Вот документация https://docs.angularjs.org/api/ng/directive/ngModelOptions
Ответ 3
Хотя @charlietfl предоставил полностью приемлемый ответ, я хотел бы поделиться с вами другим подходом без использования метода $watch
:
Шаблон:
<input id="delayedModel" ng-model="delayedModel" ng-change="callDelayed()"/>
Контроллер:
(function (timer, delay) {
$scope.callDelayed= function () {
if(timer){
$timeout.cancel(timer)
}
timer = $timeout(function(){
/* run code*/
}, delay)
};
})(false, 500);
Может быть, стоит указать, почему используется самопроизвольная анонимная функция. Основная причина заключается в том, чтобы не загрязнять область контроллера с помощью переменных time
и delay
. В этом случае они определяются в области локальных функций.
[ОБНОВЛЕНИЕ]
Я также нашел интересный проект AngularJS под названием angular-debounce, что делает его очень простым для достижения такого же эффекта. Используя директиву debounce
, можно развернуть обновление модели следующим образом:
<input type="text" ng-model="delayedModel" debounce="500"></input>