【问题标题】:Input does not disable on resetting a Reactive Form in Angular 6在Angular 6中重置反应表单时输入不会禁用
【发布时间】:2020-11-02 10:35:41
【问题描述】:

我为我的问题创建了一个StackBlitz example

我有一个FormService,它构建了一个表单,由组件在initForm()方法中获取:-

public getForm() {
  return this.fb.group({
    cb1: this.fb.control(false),
    cb2: this.fb.control(false),
    inputBox: this.fb.control({value: '', disabled: true}, Validators.required)
  });
}

如果没有选中任何复选框,我需要禁用输入文本框。这让我做这样的事情:-

if(!this.cb1.value && !this.cb2.value) {
  this.isCheckboxSelectionInvalid = true;
  this.inputBox.disable();
} else {
  this.isCheckboxSelectionInvalid = false;
  this.inputBox.enable();
}

这适用于所有默认情况 - 但是有一个问题。当我调用resetForm()(如果通过选中其中一个复选框启用输入)基本上调用initForm()的相同方法时,输入保持启用状态。即使在我调用验证复选框选择并禁用initForm() 方法中的输入的方法之后也是如此。

出于理智,我记录了输入的 disabled 属性的值 - 记录了 true

为什么输入没有被禁用呢?任何帮助将不胜感激,这是工作中的一个问题。

【问题讨论】:

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


    【解决方案1】:

    您面临的问题与一个角度错误有关,您可以找到更多信息here

    有一些对我有用的解决方法:

    1. 在 setTimeout 中调用禁用函数。
    validateCheckboxSelectionAndChangeInputState() {
      if (!this.cb1.value && !this.cb2.value) {
         this.isCheckboxSelectionInvalid = true;
         setTimeout(() => {
            this.inputBox.disable();
         }, 0);
      } else {
         this.isCheckboxSelectionInvalid = false;
         this.inputBox.enable();
      }
    }
    
    1. 直接设置disabled属性:
    <input type="text" [attr.disabled]="form.controls['inputBox'].disabled" formControlName="inputBox" />
    
    1. 在调用启用/禁用函数之前调用 detectChanges。
    validateCheckboxSelectionAndChangeInputState() {
      this.ref.detectChanges();
      if (!this.cb1.value && !this.cb2.value) {
        this.isCheckboxSelectionInvalid = true;
        this.inputBox.disable();
      } else {
          this.isCheckboxSelectionInvalid = false;
          this.inputBox.enable();
      }
    }
    
    

    与问题无关的建议:


    有启用或禁用控件的想法,可以订阅表单valueChanges

      initForm() {
        this.form = this.formService.getForm();
        this.cb1 = this.form.get("cb1");
        this.cb2 = this.form.get("cb2");
        this.inputBox = this.form.get("inputBox");
        this.form.valueChanges.subscribe(
          this.validateCheckboxSelectionAndChangeInputState.bind(this)
        );     
      }
    
      validateCheckboxSelectionAndChangeInputState(controls) {
        if (this.inputBox.disabled && controls.cb1 && controls.cb2) {
          this.inputBox.enable();
        } 
        if(this.inputBox.enabled && !controls.cb1 && !controls.cb) {
           setTimeout(() => {
              this.inputBox.disable();
           }, 0);
        } 
      }
    
      toggleCb1() {
        this.cb1.setValue(!this.cb1.value);
      }
    
      toggleCb2() {
        this.cb2.setValue(!this.cb2.value);
      }
    
      resetForm() {
        this.initForm();
      }
    

    您还可以使用 form.valid 并使用 Validators.requiredTrue [禁用] 按钮:

    html

     <button [disabled]="!form.valid" (click)="submitForm()">
        Submit
      </button>
    

    ts

    public getForm() {
        return this.fb.group({
          cb1: this.fb.control(false, [Validators.requiredTrue]),
          cb2: this.fb.control(false, [Validators.requiredTrue]),
          inputBox: this.fb.control(
            { value: "", disabled: true },
            [Validators.required]
          )
        });
      }
    

    https://stackblitz.com/edit/angular-6-reactive-form-disable-jn4cf8?file=src%2Fapp%2Fapp.component.ts

    【讨论】:

    • 这仍然不起作用。试试这个 - 通过打开两个复选框来启用 inputBox。在 inputBox 中输入一些内容,然后单击“重置”按钮。期望 - 因为两者都是false,所以inputBox 应该是disabled。现实 - inputBoxenabled,我们可以输入它。
    • 这在 Angular 本身的实现方式上看起来越来越像一个错误。
    • 是的,我看到输入没有被禁用,我添加了一个 setTimeout(() => { this.inputBox.disable(); }, 0);它的工作原理,很奇怪
    • 嘿,很好的发现!我试图先找到它,但无济于事。 setTimeout 破解虽然有效!接受这个答案。
    【解决方案2】:

    不创建另一个表单实例,并实际重置现有表单怎么样?

      resetForm() {
        this.form.reset({
          cb1: false,
          cb2: false
        });
        this.validateCheckboxSelectionAndChangeInputState();
      }
    

    https://stackblitz.com/edit/angular-6-reactive-form-disable-pefhmc

    【讨论】:

    • 不起作用。也试过了。这是因为在调用reset 时,表单值设置为null。这不会禁用输入。
    • 编辑。但您应该考虑添加 FormGroup 验证。
    猜你喜欢
    • 2019-02-05
    • 2019-03-23
    • 2019-03-08
    • 2017-03-16
    • 2019-05-29
    • 2019-06-24
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多