繁体   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