簡體   English   中英

Angular 2:去抖動(ngModelChange)?

[英]Angular 2: Debounce (ngModelChange)?

有沒有辦法去抖動模板指令(ngModelChange)

或者,換種方式,以不同的方式做這件事的最不痛苦的方法是什么?

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

所以,例如,我有一個文本輸入,我想獲得 onChange 更新,但我想從每次擊鍵中消除它:

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

去抖動onFieldChange()

編輯

例如,在 Angular 的新版本中,您可以使用ngModelOption updateOn來設置'blur' 鏈接到 angular.io 文檔

代碼示例:

<input [(ngModel)]="value"
  [ngModelOptions]="{ updateOn: 'blur' }"
  (ngModelChange)="updateOnlyOnBlur($event)"> 

遺產

如果您不想使用formcontrol方法,這里有一種不那么痛苦的擊鍵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);
    }
}

對於 RxJs 6+

所選答案不適用於 RxJs 6+。 這是您必須更改的內容:

進口必須是這樣的:

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

您需要調用pipe

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

請查看這篇文章以進一步閱讀。

我寫了一個小指令來解決這個問題。

如何使用它:

<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

如果您想在進行 http 調用時添加debounceTime ,您可以使用非常易於使用的Subject 這也在 angular2 教程 - HTTP 中進行了解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM