Angular 2:Debounce(ngModelChange)?

时间:2016-12-23 23:13:26

标签: javascript angular

有没有办法去抖模板指令(ngModelChange)

或者,或者,以不同的方式做最不痛苦的方式是什么?

我看到的最接近的答案是:How to watch for form changes in Angular 2?

所以,例如,我有一个文本输入,我想获得更改更新,但我想从每次击键中去掉它:

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

去抖动onFieldChange()

4 个答案:

答案 0 :(得分:30)

如果您不想使用formcontrol方法,这就是减少击键次数的痛苦方法。

  

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

答案 1 :(得分:10)

我写了一个小指令来解决这个问题。

如何使用它:

<input [ngModel]="someValue" (ngModelChangeDebounced)="someValue = $event">

您可以选择设置反跳时间(默认为500):

[ngModelChangeDebounceTime]="200"

指令本身:

@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

答案 2 :(得分:7)

Sangram Nandkhile给出的answer不适用于RxJ 6+。这是您必须更改的内容:

导入必须如下所示:

import {Subject} from "rxjs";
import {debounceTime, distinctUntilChanged} from "rxjs/internal/operators";

您需要致电pipe

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

看看this article以便进一步阅读。

答案 3 :(得分:4)

如果您想在进行http呼叫时添加debounceTime,可以使用Subject,这非常容易使用。这也在angular2 tutorial - HTTP中进行了解释。