在Angular 6中重置响应式表单时,输入不会禁用 [英] Input does not disable on resetting a Reactive Form in Angular 6

查看:113
本文介绍了在Angular 6中重置响应式表单时,输入不会禁用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的问题创建了一个 StackBlitz示例./p>

我有一个 FormService 可以构建一个表单,该表单是由 initForm()方法中的组件获取的:-

  public getForm(){返回this.fb.group({cb1:this.fb.control(false),cb2:this.fb.control(false),inputBox:this.fb.control({value:``,disable:true},Validators.required)});} 

如果未选中任何复选框,则需要禁用输入文本框.这使我可以做这样的事情:-

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

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

为了简洁起见,我记录了输入的 disabled 属性的值-记录了 true .

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

解决方案

您面临的问题与角度错误有关,您可以找到更多信息 validateCheckboxSelectionAndChangeInputState(){if(!this.cb1.value&&!this.cb2.value){this.isCheckboxSelectionInvalid = true;setTimeout(()=> {this.inputBox.disable();},0);} 别的 {this.isCheckboxSelectionInvalid = false;this.inputBox.enable();}}

  1. 直接设置禁用的属性:

 < 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();} 别的 {this.isCheckboxSelectionInvalid = false;this.inputBox.enable();}} 


与问题无关的建议


启用或禁用控件的想法,您可以订阅

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

html

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

ts

  public getForm(){返回this.fb.group({cb1:this.fb.control(false,[Validators.requiredTrue]),cb2:this.fb.control(false,[Validators.requiredTrue]),inputBox:this.fb.control({值:",已禁用:true},[Validators.required])});} 

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

I have created a StackBlitz example of my problem.

I have a FormService that builds a form, which is obtained by the component in the initForm() method:-

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)
  });
}

I need to disable the input text box if none of the checkboxes is selected. Which brings me to do something like this :-

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

This works for all default scenarios - however there is a problem. When I call resetForm() (provided the input is enabled by checking one of the checkboxes) which basically calls the same method of initForm(), the input stays enabled. This is even after I call the method that validates checkbox selection and disables the input in the initForm() method.

For sanity, I logged the value of the input's disabled property - which logs true.

Why is it that the input doesn't get disabled then? Any help would be very appreciated, this is a problem at work.

解决方案

The problem you are facing is related to an angular bug, you can find more info here.

There are some workarounds that worked for me:

  1. Call disable function inside 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. Set directly the disabled attribute:

<input type="text" [attr.disabled]="form.controls['inputBox'].disabled" formControlName="inputBox" />

  1. Call detectChanges before calling enable/disable functions.

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


Suggestions not related to the problem:


With the idea of ​​enabling or disabling the control, you can subscribe to form 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();
  }

Also you can [disabled] the button using form.valid, and using the 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]
      )
    });
  }

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

这篇关于在Angular 6中重置响应式表单时,输入不会禁用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆