【问题标题】:form async validation when updateOn is blur, to subscribe statusChanges or valueChanges当 updateOn 模糊时形成异步验证,订阅 statusChanges 或 valueChanges
【发布时间】:2019-12-02 09:09:35
【问题描述】:

我在我的 Angular7 应用程序中使用带有 updatOn: 'blur' 的表单异步验证。 stackblitz

在这种情况下,我需要检查名称是否唯一(异步验证)。

this.myForm.get('name').statusChanges.subscribe(status => {
    if (status === 'VALID') {
        // to save the name to database.
    } else {
        // to show some errors.
    }
});

问题是,这段代码放在哪里?

当前方式

我在子组件中试过这个

@Input()
set myForm(myForm: FormGroup) {
  this._myForm = myForm;
  this.myForm.get('name').statusChanges.subscribe(status => {    // to subscribe statusChanges here.
    if (status === 'VALID') {
        // to save the name to database.
    } else {
        // to show some errors.
    }
  });
}

get myForm() {
  return this._myForm;
}


_myForm: FormGroup

成功了。但是我至少有 10 个属性要做表单验证,这会给这个@Input() set myForm() {} 添加太多代码,所以我需要在另一个函数中执行此操作。

所以,我退出订阅@Input 属性中的statusChange。如果不在这里,我应该在哪里做呢?

我无法订阅ngOnInit 中的statusChange,因为ngOnInit 中的值未定义。

请大家帮帮我。

【问题讨论】:

  • @MoxxiManagarm 是的,但我仍然需要验证结果来决定下一步应该做什么。

标签: angular forms angular2-form-validation


【解决方案1】:

我认为您可以在这种情况下使用directive - 创建一个指令并添加必要的input 字段

指令

@Directive({
  selector: '[dynamicValidation]'
})
export class DynamicValidationDirective {

  constructor(private control: NgControl) { }

  ngOnInit() {
    if (this.control && this.control!= undefined) {
      this.control.statusChanges.subscribe((status) => {
        // Your logic will go here
      });
    }       
  }
}

现在只需在特定输入字段中添加directive

输入

<input [formControlName]="controlName"
                         type="text"
                         dynamicValidation        //Added the directive
                         class="form-control form-control-sm" />

现在所有输入字段都将被标记为订阅,并且当状态更改时,特定输入值将分别更新

希望这对您有所帮助 - 谢谢!!

【讨论】:

  • 你的方法奏效了,但我有一个问题让我很困惑。我在指令@Input() control: FormGroup; 和模板&lt;input type="text" formControlName="name" dynamicValidation [control]="rowData" 中使用了数据绑定。但是数据绑定工作了两次。第一次获取之前的值,第二次获取更改后的值
  • 是的,当页面加载第一次时,订阅会被触发,然后当状态发生变化时,订阅会被触发——如果你想避免第一次订阅并只在状态改变时处理你的代码- 你可以在订阅中使用control.touched 属性 - 所以只有当控件被触摸时才会允许 - 希望它有所帮助
  • 不,不是因为这个。我设置了验证updateOn: 'blur'。验证完成后,数据绑定工作两次。在blur 发生后,我得到了先前的值和改变的值
  • 在指令中我这样做了:this.control.valueChanges.subscribe(value =&gt; { console.log('valueChange:', this.control.value.name); }); this.control.statusChanges.subscribe(status =&gt; { if (status === 'VALID') { console.log('statusChange:', this.rowControl.value.name); } else { console.log('validation failed'); } }); 输出是:statusChange: previousName; valueChange: changedName; statusChange: changedName;
  • 那么在你的情况下最好使用valueChanges 而不是statusChanges - 但请确保valueChanges 将触发输入的每次更改
猜你喜欢
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2023-01-04
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多