В AngularJS я могу опровергнуть модель, используя параметры ng-model.
ng-model-options="{ debounce: 1000 }"
Как я могу разоблачить модель в Angular? Я пытался найти debounce в документах, но ничего не смог найти.
https://angular.io/search/#stq=debounce&stp=1
Решением было бы написать мою собственную функцию debounce, например:
import {Component, Template, bootstrap} from 'angular2/angular2';
// Annotation section
@Component({
selector: 'my-app'
})
@Template({
url: 'app.html'
})
// Component controller
class MyAppComponent {
constructor() {
this.firstName = 'Name';
}
changed($event, el){
console.log("changes", this.name, el.value);
this.name = el.value;
}
firstNameChanged($event, first){
if (this.timeoutId) window.clearTimeout(this.timeoutID);
this.timeoutID = window.setTimeout(() => {
this.firstName = first.value;
}, 250)
}
}
bootstrap(MyAppComponent);
И мой HTML
<input type=text [value]="firstName" #first (keyup)="firstNameChanged($event, first)">
Но я ищу встроенную функцию, есть ли такая в Angular?
javascript
angular
koningdavid
источник
источник
Ответы:
Обновлено для RC.5
С Angular 2 мы можем отсеивать, используя оператор RxJS
debounceTime()
вvalueChanges
наблюдаемом элементе управления формы :Plunker
Приведенный выше код также включает в себя пример того, как регулировать события изменения размера окна, как это спросил @albanx в комментарии ниже.
Хотя приведенный выше код, вероятно, является угловым способом сделать это, он неэффективен. Каждое нажатие клавиши и каждое событие изменения размера, даже если они отменяются и регулируются, приводит к выполнению обнаружения изменений. Другими словами, устранение неполадок и регулирование не влияют на частоту выполнения обнаружения изменений . (Я нашел комментарий GitHub от Тобиаса Боша, который подтверждает это.) Это можно увидеть, когда вы запускаете плункер, и видите, сколько раз
ngDoCheck()
вызывается, когда вы вводите в поле ввода или изменяете размер окна. (Используйте синюю кнопку «x» для запуска плунжера в отдельном окне, чтобы увидеть события изменения размера.)Более эффективный метод заключается в создании RxJS Observables самостоятельно из событий за пределами «зоны» Angular. Таким образом, обнаружение изменений не вызывается каждый раз, когда происходит событие. Затем в ваших методах обратного вызова подписки инициируйте обнаружение изменений вручную, т.е. вы управляете, когда вызывается обнаружение изменений:
Plunker
Я использую
ngAfterViewInit()
вместо того,ngOnInit()
чтобы убедиться, чтоinputElRef
это определено.detectChanges()
запустит обнаружение изменений на этом компоненте и его дочерних элементах. Если вы предпочитаете запускать обнаружение изменений из корневого компонента (т. Е. Выполнять полную проверку обнаружения изменений), используйтеApplicationRef.tick()
вместо этого. (Я помещаю вызовApplicationRef.tick()
в комментарии в плунжере.) Обратите внимание, что вызовtick()
вызоветngDoCheck()
вызов.источник
.fromEvent()
подпискиЕсли вы не хотите иметь дело
@angular/forms
, вы можете просто использовать RxJSSubject
с привязками изменений.view.component.html
view.component.ts
Это вызывает обнаружение изменений. Для способа, который не вызывает обнаружение изменений, проверьте ответ Марка.
Обновить
.pipe(debounceTime(300), distinctUntilChanged())
нужен для rxjs 6.Пример:
источник
.pipe(debounceTime(300), distinctUntilChanged())
нужен для rxjs 6keyUp
событие oninput.nativeElement
вmat-table
, которое перестало работать, когда количество столбцов было измененоЭто может быть реализовано как директива
используйте это как
образец компонента
источник
import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged';
наimport { debounceTime, distinctUntilChanged } from 'rxjs/operators';
иthis.model.valueChanges .debounceTime(this.debounceTime) .distinctUntilChanged()
наthis.model.valueChanges .pipe( debounceTime(this.debounceTime), distinctUntilChanged() )
Поскольку тема старая, большинство ответов не работают на Angular 6/7/8/9 и / или не используют другие библиотеки.
Итак, вот краткое и простое решение для Angular 6+ с RxJS.
Сначала импортируйте необходимые вещи:
Инициализировать на
ngOnInit
:Используйте этот способ:
PS: для более сложных и эффективных решений вы все еще можете проверить другие ответы.
источник
Непосредственно недоступен, как в angular1, но вы легко можете играть с наблюдаемыми NgFormControl и RxJS:
Это сообщение в блоге объясняет это ясно: http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
Здесь это для автозаполнения, но это работает во всех сценариях.
источник
[...]
одностороннее целевое связывание. Почему контейнер может быть уведомленvalueChanges
? не должно быть что-то. как(ngFormControl)="..."
?Вы можете создать в RxJS (V.6) Observable что делает все , что вам нравится.
view.component.html
view.component.ts
источник
rsjs/Rx
, у меня были ошибки при использовании импорта, как вы написали ... так что в моем случае это сейчас:import { Observable } from 'rxjs/Rx';
import { Observable } from 'rxjs';
.pipe
вызовpipe(debounceTime(300), distinctUntilChanged())
Для тех, кто использует lodash, очень легко отменить любую функцию:
затем просто добавьте что-то подобное в ваш шаблон:
источник
Решение с инициализацией абонента непосредственно в функции события:
И HTML:
источник
Я решил это, написав декоратор debounce. Описанная проблема может быть решена путем применения @debounceAccessor к аксессору набора свойств.
Я также предоставил дополнительный декоратор debounce для методов, которые могут быть полезны в других случаях.
Это позволяет очень легко отменить свойство или метод. Параметр - это количество миллисекунд, которое должно длиться отладке, 100 мс в примере ниже.
А вот код для декораторов:
Я добавил дополнительный параметр для декоратора метода, который позволяет вам вызывать метод ПОСЛЕ задержки задержки. Я сделал это, чтобы, например, использовать его в сочетании с событиями при наведении курсора мыши или изменении размера, где я хотел, чтобы захват происходил в конце потока событий. В этом случае, однако, метод не будет возвращать значение.
источник
Мы можем создать директиву [debounce], которая перезаписывает функцию viewToModelUpdate по умолчанию в ngModel пустой.
Директива Код
Как это использовать
источник
HTML-файл:
TS файл:
источник
Простым решением было бы создать директиву, которую вы можете применить к любому элементу управления.
использование будет
источник
Angular 7
.Потратил на это часы, надеюсь, я смогу спасти кого-нибудь еще. Для меня следующий подход к использованию
debounce
на элементе управления является более интуитивным и легче для меня. Он основан на решении angular.io docs для автозаполнения, но с возможностью перехвата вызовов без необходимости привязывать данные к DOM.Plunker
Сценарий использования для этого может быть проверка имени пользователя после его ввода, чтобы увидеть, если кто-то уже взял его, а затем предупреждение пользователя.
Примечание: не забывайте,
(blur)="function(something.value)
может иметь больше смысла для вас в зависимости от ваших потребностей.источник
DebounceTime в Angular 7 с RxJS v6
Ссылка на источник
Демо- ссылка
В шаблоне HTML
В компоненте
источник
Вы также можете решить эту проблему с помощью декораторов, например, с помощью декоратора debounce из utils-decorator lib (
npm install utils-decorators
):источник
Это лучшее решение, которое я нашел до сих пор. Обновления
ngModel
наblur
иdebounce
как заимствовано из https://stackoverflow.com/a/47823960/3955513
Тогда в HTML:
На
blur
модели явно обновляется с использованием простого javascript.Пример здесь: https://stackblitz.com/edit/ng2-debounce-working
источник