Angular 重新输入相同值时不会触发ngModelChange

Angular 重新输入相同值时不会触发ngModelChange,angular,rxjs,ngrx,Angular,Rxjs,Ngrx,我试图在数字输入字段上实现最大值限制,这样当用户尝试输入高于限制的值时,输入字段将重置为允许的最大值。之后,reducer接收到一个操作,更新存储中的值 下面是示例代码。请原谅代码太差:我对RXJS/NGRX非常缺乏经验。如果有人有更好的解决办法,我洗耳恭听 组件技术 导出类InputAmountComponent实现OnInit{ @Input()公共项:FormGroup; @Input()公共appState:appState; @Output()公共InputMountEmitter:E

我试图在数字输入字段上实现最大值限制,这样当用户尝试输入高于限制的值时,输入字段将重置为允许的最大值。之后,reducer接收到一个操作,更新存储中的值

下面是示例代码。请原谅代码太差:我对RXJS/NGRX非常缺乏经验。如果有人有更好的解决办法,我洗耳恭听

组件技术

导出类InputAmountComponent实现OnInit{
@Input()公共项:FormGroup;
@Input()公共appState:appState;
@Output()公共InputMountEmitter:EventEmitter=新的EventEmitter();
inputChanged$:主题=新主题();
maxAmount=environment.defaultMaxAmountPayablePoundsOrDollars;
构造函数(专用存储:存储,专用路由:ActivatedRoute){
此.inputChanged$.pipe(
去BounceTime(300),
)
.订阅((新值)=>{
if(this.maxAmount&&newValue>this.maxAmount){
console.log('重置')
this.item.controls['amount'].setValue(this.maxAmount);
}
否则{
console.log('dispatching')
this.store.dispatch(newappactions.UpdateAmount(newValue));
}
});
}
updateValue(newValue:number){
console.log('changed')
if(this.getAmount().valid){
this.inputChanged$.next(newValue);
}
}
//…代码的其余部分
component.html

../more html
…//更多html
在测试此解决方案时,我遇到了这种奇怪的行为:

  • 用户输入330000
  • 应用程序重置为30000(允许的最大值)
  • 用户再次输入330000
  • 没有发生任何情况(但我希望按照步骤2进行重置)
  • 与之相比:

  • 用户输入330000
  • 应用程序重置为30000(允许的最大值)
  • 用户输入320000
  • 应用程序重置为30000

  • 有人能解释为什么会发生这种情况,以及我如何解决它吗?

    不要将
    ngModel
    ngModelChange
    与被动形式一起使用。在Angular的旧版本中,这被认为是一种不好的做法,Angular 7中放弃了(或者至少应该放弃)对混合的支持。 如果在角度>=7的情况下使用此选项,则应引发警告或错误

    无论如何-删除
    ngModelChange
    ,删除整个
    inputChanged$
    ,因为它不需要

    // Subscribe directly to changes in the form
    this.item.get('amount').valueChanges
      .pipe(
        debounceTime(300),
      )
      .subscribe(newValue => {
        if (this.maxAmount && newValue > this.maxAmount) {
          console.log('resetting');
          // Update the value without emitting event so you don't enter endless loop.
          this.item.get('amount').setValue(this.maxAmount, {
            emitEvent: false
          });
        }
        else {
          console.log('dispatching');
          this.store.dispatch(new AppActions.UpdateAmount(newValue));
        }
      });
    
    从我的头顶写下来的,所以要带点盐。 另外,我认为
    required
    也应该由验证器处理,而不是作为标记的一部分-您可能会遇到同样的问题,因为它不适用于被动表单

    另一方面,在大多数用例中,以这种方式更新值被认为是不好的UX。通常情况下,添加一个验证器会更好,只要输入值无效,就会显示一个验证错误。通过这种方式,您可以让用户知道哪里出了问题,并让他手动将错误修复为此选择的值