以反应形式禁用输入字段


117

我已经尝试遵循此处其他答案的示例,但未成功!

我创建了一个响应式表单(即动态表单),并且想在任何给定时间禁用某些字段。我的表格代码:

this.form = this._fb.group({
  name: ['', Validators.required],
  options: this._fb.array([])
});

const control = <FormArray>this.form.controls['options'];
control.push(this._fb.group({
  value: ['']
}));

我的html:

<div class='row' formArrayName="options">
  <div *ngFor="let opt of form.controls.options.controls; let i=index">
    <div [formGroupName]="i">
      <select formArrayName="value">
        <option></option>
        <option>{{ opt.controls.value }}</option>
      </select>
    </div>
  </div>
</div>

我减少了代码以方便使用。我想禁用类型选择的字段。我尝试执行以下操作:

form = new FormGroup({
  first: new FormControl({value: '', disabled: true}, Validators.required),
});

不工作!有人有建议吗?


当您尝试禁用一些称为first?`的formcontrol时,如何禁用选择呢?)
AJT82

这只是错字。我想禁用选择。你能帮助我吗?
Renato Souza de Oliveira'Mar

你能重现一个矮人吗?
AJT82

您是否要禁用整个选择?而value不是formArray,这是一个formControlName。如果要value成为formArray,则必须对其进行更改。当前是一个formControlName。因此,如果您想禁用整个选择字段,只需更改<select formArrayName="value"><select formControlName="value">
AJT82

Answers:


219
name: [{value: '', disabled: true}, Validators.required],
name: [{value: '', disabled: this.isDisabled}, Validators.required],

要么

this.form.controls['name'].disable();

如果我设置像这样的值->国家:[{值:this.address.country,已禁用:true}]该值不填
Silvio Troia

我使用了相同的技术来禁用从可信来源自动填充的字段。我有一个启用/禁用表单的开关,并且在启用整个表单后,通常会使用if语句禁用那些字段。提交表单后,整个表单将再次被禁用。
retr0

72

请注意

如果要使用条件变量创建表单并稍后尝试对其进行更改,则该表单将不起作用,即表单将不会更改

例如

this.isDisabled = true;

this.cardForm = this.fb.group({
    'number': [{value: null, disabled: this.isDisabled},
});

如果您更改变量

this.isDisabled = false;

形式不会改变。你应该用

this.cardForm.get('number')。disable();

顺便说一句。

您应该使用patchValue方法更改值:

this.cardForm.patchValue({
    'number': '1703'
});

22

在具有反应形式的DOM中使用禁用是一种不好的做法。FormControl当您从中初始化时,可以在中设置此选项

username: new FormControl(
  {
    value: this.modelUser.Email,
    disabled: true
  },
  [
    Validators.required,
    Validators.minLength(3),
    Validators.maxLength(99)
  ]
);

财产value是没有必要的

或者您可以使用get('control_name')并设置表单控件disable

this.userForm.get('username').disable();

为什么在带有反应形式的DOM中使用disable是一种不好的做法?
南瓜

2
您将收到角度警告。 It looks like you’re using the disabled attribute with a reactive form directive. If you set disabled to true when you set up this control in your component class, the disabled attribute will actually be set in the DOM for you. We recommend using this approach to avoid ‘changed after checked’ errors。因此,建议直接通过控件更改禁用/启用状态的方法。此外,您还可以检查这个伟大的主题 netbasal.com/...
沃洛Khmil

10

我通过将输入对象及其标签包装在字段集中来解决此问题:字段集应将disable属性绑定到boolean

 <fieldset [disabled]="isAnonymous">
    <label class="control-label" for="firstName">FirstName</label>
    <input class="form-control" id="firstName" type="text" formControlName="firstName" />
 </fieldset>

1
浪费大量时间弄清楚如何以反应形式禁用控件,大声笑!这工作..不需要指令或额外的代码。欢呼声🍻
的Nexus

7

所述disablingFormControl prevents它存在于,在成形saving。您可以将其设置为readonly属性。

您可以通过以下方式实现:

HTML:

<select formArrayName="value" [readonly] = "disableSelect">

TS:

this.disbaleSelect = true;

在这里找到这个


2
您可以form.getRawValue()用来包括禁用的控件值
Murhaf Sousli

6

如果使用disabled表单输入元素(如正确答案中建议的 如何禁用输入),对它们的验证也将被禁用,请注意这一点!

(并且,如果您使用的是“提交”按钮[disabled]="!form.valid",则会从验证中排除您的字段)

在此处输入图片说明


1
如何验证最初禁用但动态设置的字段?
NeptuneOyster

5

一种更通用的方法是。

// Variable/Flag declare
public formDisabled = false;

// Form init
this.form = new FormGroup({
  name: new FormControl({value: '', disabled: this.formDisabled}, 
    Validators.required),
 });

// Enable/disable form control
public toggleFormState() {
    this.formDisabled = !this.formDisabled;
    const state = this.formDisabled ? 'disable' : 'enable';

    Object.keys(this.form.controls).forEach((controlName) => {
        this.form.controls[controlName][state](); // disables/enables each form control based on 'this.formDisabled'
    });
}

3

如果要禁用first(formcontrol),则可以使用以下语句。

this.form.first.disable();



3
this.form.enable()
this.form.disable()

或formcontrol'first'

this.form.get('first').enable()
this.form.get('first').disable()

您可以设置禁用或启用初始设置。

 first: new FormControl({disabled: true}, Validators.required)


1

最好的解决方案在这里:

https://netbasal.com/disabling-form-controls-when-working-with-reactive-forms-in-angular-549dd7b42110

解决方案概述(如果链接断开):

(1)创建指令

import { NgControl } from '@angular/forms';

@Directive({selector: '[disableControl]'})
export class DisableControlDirective {

  @Input() set disableControl( condition : boolean ) {
    const action = condition ? 'disable' : 'enable';
    this.ngControl.control[action]();
  }

  constructor( private ngControl : NgControl ) {}
}

(2)像这样使用

<input [formControl]="formControl" [disableControl]="condition">

(3)由于禁用的输入不会在提交时显示在form.value中,因此您可能需要使用以下内容(如果需要):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}

我尝试过这种方式。在提取API数据后,我将显示大多数FormControls,因此在使用formControl将值设置/修补到我this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE)的formControl之后。当它传递给指令时,它显示无法读取未定义的属性“ disable”
ImFarhad

0

我有同样的问题,但是调用this.form.controls ['name']。disable()并不能解决它,因为我正在重新加载视图(使用router.navigate())。

就我而言,我必须在重新加载之前重置表单:

this.form =未定义;this.router.navigate([path]);



0

您可以声明一个函数来启用/禁用所有表单控件:

  toggleDisableFormControl(value: Boolean, exclude = []) {
    const state = value ? 'disable' : 'enable';
    Object.keys(this.profileForm.controls).forEach((controlName) => {
      if (!exclude.includes(controlName))
        this.profileForm.controls[controlName][state]();
    });
  }

像这样使用

this.toggleDisableFormControl(true, ['email']);
// disbale all field but email

-2

为了使一个场禁用启用反应形式角2+

1. 禁用

  • [attr.disabled] =“ true”添加到输入。

<input class="form-control" name="Firstname" formControlName="firstname" [attr.disabled]="true">

启用

export class InformationSectionComponent {
formname = this.formbuilder.group({
firstname: ['']
});
}

启用整个表格

this.formname.enable();

单独启用特定字段

this.formname.controls.firstname.enable();

与disable相同,将enable()替换为disable()。

这很好。注释查询。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.