Angular 2: Debounce (ngModelChange)?

2020-02-09 00:47发布

问题:

Is there a way to debounce the template directive (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?

So, for example, I have a text input, I want to get onChange updates, but I want to debounce it down from every keystroke:

<input type="text" class="form-control" placeholder="Enter a value" name="foo" [(ngModel)]="input.event.value" (ngModelChange)="onFieldChange($event, input)">

Debounce onFieldChange()

回答1:

Here's the less painful way of debouncing keystrokes if you don't want to use the formcontrol approach.

search.component.html

<input type="text" placeholder="Enter a value" name="foo" [(ngModel)]="txtQuery" (ngModelChange)="onFieldChange($event)">

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);
    }
}


回答2:

The answer given by Sangram Nandkhile won't work for 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/internal/operators";

You need to call pipe:

// ...
this.txtQueryChanged
   .pipe(debounceTime(1000), distinctUntilChanged())
   .subscribe(model => {
       this.txtQuery = model;
       // api call
   });
 // ...

Take a look at this article for further reading.



回答3:

If you wanted to add debounceTime while doing http call you can use Subject which is very easy to use . Which is also explained in angular2 tutorial - HTTP.