[英]Angular 2: Debounce (ngModelChange)?
Is there a way to debounce the template directive (ngModelChange)
?有没有办法去抖动模板指令
(ngModelChange)
?
Or, alternatively, what is the least-painful way to do it a different way?或者,换种方式,以不同的方式做这件事的最不痛苦的方法是什么?
The closest answer I see is this: How to watch for form changes in Angular 2?我看到的最接近的答案是: How to watch for form changes in Angular 2?
So, for example, I have a text input, I want to get onChange updates, but I want to debounce it down from every keystroke:所以,例如,我有一个文本输入,我想获得 onChange 更新,但我想从每次击键中消除它:
<input type="text" class="form-control" placeholder="Enter a value" name="foo" [(ngModel)]="input.event.value" (ngModelChange)="onFieldChange($event, input)">
Debounce onFieldChange()
去抖动
onFieldChange()
EDIT编辑
In new version of Angular you can use updateOn
in ngModelOption
to set 'blur'
for example.例如,在 Angular 的新版本中,您可以使用
ngModelOption
updateOn
来设置'blur'
。 Link to angular.io documentation .链接到 angular.io 文档。
Code example :代码示例:
<input [(ngModel)]="value"
[ngModelOptions]="{ updateOn: 'blur' }"
(ngModelChange)="updateOnlyOnBlur($event)">
LEGACY遗产
Here's the less painful way of debouncing keystrokes if you don't want to use the formcontrol
approach.如果您不想使用
formcontrol
方法,这里有一种不那么痛苦的击键formcontrol
方法。
search.component.html
search.component.html
<input type="text" placeholder="Enter a value" name="foo" [(ngModel)]="txtQuery" (ngModelChange)="onFieldChange($event)">
search.component.ts
search.component.ts
export class SearchComponent {
txtQuery: string; // bind this to input with ngModel
txtQueryChanged: Subject<string> = new Subject<string>();
constructor() {
this.txtQueryChanged
.debounceTime(1000) // wait 1 sec after the last event before emitting last event
.distinctUntilChanged() // only emit if value is different from previous value
.subscribe(model => {
this.txtQuery = model;
// Call your function which calls API or do anything you would like do after a lag of 1 sec
this.getDataFromAPI(this.txtQuery);
});
}
onFieldChange(query:string){
this.txtQueryChanged.next(query);
}
}
The chosen answer won't work for RxJs 6+.所选答案不适用于 RxJs 6+。 Here is what you have to change:
这是您必须更改的内容:
The imports have to look like this:进口必须是这样的:
import {Subject} from "rxjs";
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
You need to call pipe
:您需要调用
pipe
:
// ...
this.txtQueryChanged
.pipe(debounceTime(1000), distinctUntilChanged())
.subscribe(model => {
this.txtQuery = model;
// api call
});
// ...
Take a look atthis article for further reading.请查看这篇文章以进一步阅读。
I've written a little directive to solve this.我写了一个小指令来解决这个问题。
How to use it:如何使用它:
<input [ngModel]="someValue" (ngModelChangeDebounced)="someValue = $event">
You can optionally set a debounce time (default is 500):您可以选择设置去抖动时间(默认为 500):
[ngModelChangeDebounceTime]="200"
The directive itself:指令本身:
@Directive({
selector: '[ngModelChangeDebounced]',
})
export class NgModelChangeDebouncedDirective implements OnDestroy {
@Output()
ngModelChangeDebounced = new EventEmitter<any>();
@Input()
ngModelChangeDebounceTime = 500; // optional, 500 default
subscription: Subscription;
ngOnDestroy() {
this.subscription.unsubscribe();
}
constructor(private ngModel: NgModel) {
this.subscription = this.ngModel.control.valueChanges.pipe(
skip(1), // skip initial value
distinctUntilChanged(),
debounceTime(this.ngModelChangeDebounceTime)
).subscribe((value) => this.ngModelChangeDebounced.emit(value));
}
}
Stackblitz: https://stackblitz.com/edit/angular-9-0-0-rc-1-y2q2ss Stackblitz: https ://stackblitz.com/edit/angular-9-0-0-rc-1-y2q2ss
If you wanted to add debounceTime
while doing http call you can use Subject
which is very easy to use .如果您想在进行 http 调用时添加
debounceTime
,您可以使用非常易于使用的Subject
。 Which is also explained in angular2 tutorial - HTTP .这也在 angular2 教程 - HTTP 中进行了解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.