Javascript 角度2:去盎司(ngModelChange)?

Javascript 角度2:去盎司(ngModelChange)?,javascript,angular,Javascript,Angular,有没有办法消除模板指令(ngModelChange) 或者,用另一种方式做这件事最不痛苦的方式是什么 我看到的最接近的答案是: 例如,我有一个文本输入,我想获得onChange更新,但我想从每次击键中消除它: <input type="text" class="form-control" placeholder="Enter a value" name="foo" [(ngModel)]="input.event.value" (ngModelChange)="onFieldChange(

有没有办法消除模板指令
(ngModelChange)

或者,用另一种方式做这件事最不痛苦的方式是什么

我看到的最接近的答案是:

例如,我有一个文本输入,我想获得onChange更新,但我想从每次击键中消除它:

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


Debounce
onFieldChange()

如果您想在执行http调用时添加
debounceTime
,您可以使用非常容易使用的
Subject
。这也在angular2中进行了解释。

如果您不想使用
formcontrol
方法,这里有一种不那么痛苦的按键消除方法

search.component.html


search.component.ts

导出类搜索组件{
txtQuery:string;//使用ngModel将其绑定到输入
txtQueryChanged:Subject=新主题();
构造函数(){
此.txtquery已更改
.debounceTime(1000)//在发出最后一个事件之前,在最后一个事件之后等待1秒钟
.distinctUntilChanged()//仅当值与以前的值不同时才发出
.订阅(型号=>{
this.txtQuery=模型;
//调用调用API的函数,或在延迟1秒后执行任何您想执行的操作
this.getDataFromAPI(this.txtQuery);
});
}
onFieldChange(查询:字符串){
this.txtQueryChanged.next(查询);
}
}
适用于RxJs 6+ 选择的答案不适用于RxJs 6+。以下是您必须更改的内容:

导入必须如下所示:

import {Subject} from "rxjs";
import {debounceTime, distinctUntilChanged} from "rxjs/internal/operators";
您需要调用
管道

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

请进一步阅读。

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

如何使用它:

<input [ngModel]="someValue" (ngModelChangeDebounced)="someValue = $event">
指令本身:

@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));
  }
}
@指令({
选择器:“[ngModelChangeDebounced]”,
})
导出类NgModelChangeDebouncedDirective实现OnDestroy{
@输出()

ngmodelchangedbounced=neweventemitter

这个链接可能会对你有所帮助。你可以使用一个debounce装饰器,签出:见@Willi Mentzel对这个答案的更新:有必要在订阅中将模型设置回txtQuery吗?@AugustoBarreto,因为他使用双向绑定(也称为“盒子里的香蕉”[()),这是不必要的。此时订阅正在设置此.txtQuery
,它已经由ngModelChange速记通过双向绑定进行了更新
<input [ngModel]="someValue" (ngModelChangeDebounced)="someValue = $event">
[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));
  }
}