Angular ReactiveForms - 动态设置验证器的行为意外

时间:2017-10-11 07:35:39

标签: angular typescript angular-forms reactive-forms

我正在尝试向Angular 4中的ReactiveForm添加动态验证。

我的问题是SetValidators()函数出乎意料地表现出来。

我想有这种行为:

输入字段可能为空,但 IF 用户想要输入内容,输入值必须至少为4个字符。

我不打算解释它现在的确切行为,因为我真的不知道它是怎么做的。

请查看this plunker。它非常简单并且证明了我的问题。

对我的问题:我在这里做错了什么?这是正确的方法吗?我错过了什么吗?在逻辑中还是在HTML中?

3 个答案:

答案 0 :(得分:3)

通过订阅表单控件的ValueChanges将导致此错误Maximum call stack size exceeded,最好使用其事件控制输入中的更改(例如keyup)。

并且在设置新的验证器以应用它们之后不要忘记使用updateValueAndValidity

这是您组件的新代码,现在效果很好:)

    //our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";

@Component({
  selector: 'my-app',
  template: `
    <div>
      <form [formGroup]="userForm">
        <section>
          <div>
            <label>username</label>
            <input (keyup)="inputValueChanged($event)" formControlName="username" type="text">
          </div>
          <button [disabled]="disableSaveButton()">Save</button>
        </section>
      </form>
    </div>
  `,
})
export class App implements OnInit {

  userForm: formGroup

  constructor(private formBuilder: FormBuilder) {
  }

  disableSaveButton(): boolean {
    console.log("is valid:", this.userForm.controls["username"].valid);
    return this.userForm.controls["username"].invalid
  }

  ngOnInit(): void {
    this.userForm = this.formBuilder.group({
      username: '',
    });
  }

  inputValueChanged(event){
    let  value = this.userForm.controls["username"].value;
    if (value.length > 0) {
          console.log("should be invalid if < 4")
          this.userForm.controls["username"].setValidators([Validators.required, Validators.minLength(4)]);

        } else {
          console.log("should be valid")
          this.userForm.controls["username"].setValidators([]); 
        }
        this.userForm.controls["username"].updateValueAndValidity();

  }


}

@NgModule({
  imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

希望它有助于你:)

答案 1 :(得分:2)

只需在表单声明中添加验证器,以便验证长度,但不是必需的,并删除您对valueChanges的订阅,因为它是redondant:

this.userForm = this.formBuilder.group({
  username: ['', Validators.minLength(4)],
});

我修改了your plunker

答案 2 :(得分:0)

我建议创建一个customValidator并修改此customValidator

ngOnInit(): void {
    this.userForm = this.formBuilder.group({
      username: ['',this.customValidator],
    });
}

customValidator(input:Formcontrol)
{
    let condition:boolean
    ...change condition depending some variables...
    return condition?null:{errorDesc:"Not Valid"}

}