【问题标题】:Angular ReactiveForms - Dynamically set validators behave unexpectedlyAngular ReactiveForms - 动态设置的验证器行为异常
【发布时间】:2017-10-11 07:35:39
【问题描述】:

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

我的问题是SetValidators() 函数的行为出乎意料。

我想要这种行为:

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

我不打算解释它现在的具体表现,因为我真的不知道它是怎么做的。

请查看this plunker。这很简单,可以说明我的问题。

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

【问题讨论】:

    标签: angular typescript angular-forms reactive-forms


    【解决方案1】:

    通过订阅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 {}
    

    希望对你有帮助:)

    【讨论】:

    • 谢谢,我用updateValueAndValidity 试过了,但正如你提到的,出现Maximum call stack size exceeded 错误。但按预期工作。
    • 似乎是一种不自然的条件验证方式
    【解决方案2】:

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

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

    我修改了your plunker

    【讨论】:

    • 好的,就这么简单,嗯..谢谢,+1。我接受 Medi_Ali_Rachid's 因为它正在回答我的问题。
    【解决方案3】:

    我建议制作一个 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"}
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 2018-12-20
      • 2022-07-26
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 1970-01-01
      • 2017-08-13
      相关资源
      最近更新 更多