无法将setValidators(Validators.required)从父组件设置为子组件

时间:2019-02-13 05:01:37

标签: angular nested-forms angular-reactive-forms

我有一个包含一个复选框和一个名为address的组件的表格。因此,每当用户单击复选框应用程序时,都应将地址设置为必填字段。这是我的HTML。

<form [formGroup]="registerForm">
   <app-address-input formControlName="address"></app-address-input><br>
   <input type="checkbox" formControlName="check"> Check?
</form>
<p>Form value: {{ registerForm.value | json }}</p>
<p>Form status: {{ registerForm.status | json }}</p> 

这是我的组成部分

export class AppComponent implements OnChanges {
  registerForm = new FormGroup({
      address: new FormControl(undefined),
      check: new FormControl(undefined)
  });
  get address() {
      return this.registerForm.get('address')
  }
  get check() {
      return this.registerForm.get('check')
  }
  ngOnChanges() {
      this.registerForm.get('check').valueChanges.pipe(tap(val => {
      if(val){
            this.registerForm.get('address').setValidators(Validators.required)
       }
        this.registerForm.get('address').updateValueAndValidity();
      })).subscribe();
   }
}

2 个答案:

答案 0 :(得分:2)

您应该在 ngOnInit 中订阅表单控件的valueChanges,而不是 ngOnChanges

 ngOnInit() {
        this.registerForm.get('check').valueChanges.subscribe( (val) => {
           if(val){
              console.log(val)
                 this.registerForm.get('address').setValidators(Validators.required)
            }
            this.registerForm.get('address').updateValueAndValidity();
            console.log(this.registerForm.valid);         
         });
 }

您的组件没有任何@Input(),因此不会调用 ngOnChanges 生命周期。因此无法使用表单控件的订阅。您应该在 ngOnInit 中订阅表单控件,以便订阅表单控件的valueChanges。

在Angular Docs中解释了这两个生命周期之间的差异

ngOnChanges

  

当Angular(重新)设置数据绑定的输入属性时响应。该方法接收当前和先前属性值的> SimpleChanges对象。   在ngOnInit()之前以及每当一个或多个数据绑定输入属性> change时调用。

ngOnInit

  

在Angular首先显示数据绑定>属性并设置指令/组件的输入属性后,初始化指令/组件。   在第一个ngOnChanges()之后调用一次。

答案 1 :(得分:1)

您的代码没有什么错,为什么您的订阅无法正常工作,这意味着您必须在ngOnInit()而不是ngOnChanges()生命周期挂钩中进行订阅。

每当@Input参数值更改时,就会调用

ngOnChanges()。

对于任何种类的订阅(如果您想听一些更改或订阅)。建议将该订阅放入ngOnInit()生命周期。

注意:不要忘记在ngOnDestroy()生命周期挂钩上取消订阅。

它将使您的代码免于发生任何类型的内存泄漏。