禁用反应形式的输入字段

Posted

技术标签:

【中文标题】禁用反应形式的输入字段【英文标题】:Disable Input fields in reactive form 【发布时间】:2017-08-07 23:38:21 【问题描述】:

我已经尝试按照此处其他答案的示例进行操作,但没有成功!

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

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的表单控件时,如何禁用选择?`:) 这只是错字。我想禁用选择。你能帮帮我吗? 你能复制一个 plunker 吗? 您是否要禁用整个选择?而value 不是formArray,它是formControlName。如果您希望 value 成为 formArray,则必须更改它。目前它是一个formControlName。因此,如果您希望禁用整个选择字段,只需将 &lt;select formArrayName="value"&gt; 更改为 &lt;select formControlName="value"&gt; 【参考方案1】:
name: [value: '', disabled: true, Validators.required],
name: [value: '', disabled: this.isDisabled, Validators.required],

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

【讨论】:

如果我设置这样的值 -> country: [ value: this.address.country, disabled: true ] 值不填写 我使用了相同的技术来禁用从可信来源自动填充的字段。我有一个启用/禁用表单的开关,启用整个表单后,我通常使用if 语句禁用这些字段。表单提交后,整个表单再次被禁用。 正如@retr0 所说,通常您必须在使用整个表单之前启用它们,例如,将数据提交到后端,因此用户没有机会输入从您启用它们到您将数据发送出组件的那一刻起的任何数据。 我想为值设置 null 并禁用。怎么做?我使用了 ``this.form.patchvalue( dropDown: [value: null , disbaled: true] ); `` 但它不会禁用,而是将值设置为空。任何想法【参考方案2】:

注意

如果您使用条件变量创建表单并稍后尝试更改它,它将不起作用,即表单不会更改

例如

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

【讨论】:

我遇到了同样的问题,你知道为什么它不适用于变量吗? @HarshadVekariya 因为你不传递变量,而只是传递它的值,该值在 abstractControl 的构造函数中被评估...... 谢谢!我试图为此找到文档,但我找不到,它在哪里说我们需要以这种形式传递它? 值:空,禁用:this.isDisabled @user1328889 我没说你必须这样做。如果需要更改值,只需使用 patchValue。【参考方案3】:

我通过将输入对象及其标签包装在字段集中解决了这个问题: 字段集应该将 disabled 属性绑定到布尔值

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

【讨论】:

浪费了很多时间来弄清楚如何禁用响应式表单中的控件,哈哈!这行得通..不需要指令或额外的代码。干杯? 这不是公认的答案吗?比这里的其他任何东西都容易。 这是一个很好的答案!!!我投票给你,希望你能脱颖而出。【参考方案4】:

在带有响应式表单的 DOM 中使用禁用是不好的做法。 你可以在你的FormControl中设置这个选项,当你初始化from时

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 中使用禁用是一种不好的做法? 您将收到来自 Angular 的警告。 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/…【参考方案5】:

disabling FormControl prevents 它在saving 时出现在一个表单中。您可以将其设置为 readonly 属性。

你可以通过这种方式实现它:

HTML:

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

TS:

this.disbaleSelect = true;

详情here

【讨论】:

您可以使用form.getRawValue() 包含禁用的控件值【参考方案6】:
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)

【讨论】:

为我工作。以下是如何将值同时放入控件中。 new FormControl( value: XXX, disabled: true )【参考方案7】:

一种更通用的方法是。

// 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'
    );

【讨论】:

【参考方案8】:

如果使用disabled 表单输入元素(如正确答案中所建议的) how to disable input) 对它们的验证也将被禁用,请注意!

(如果您使用[disabled]="!form.valid"这样的提交按钮,它将从验证中排除您的字段)

【讨论】:

如何验证最初禁用但动态设置的字段?【参考方案9】:

如果你想禁用first(formcontrol) 那么你可以使用下面的语句。

this.form.first.disable();

【讨论】:

【参考方案10】:

在 FormControl 中将 disabled 属性设置为 true 肯定会禁用输入字段。

this.form=this.fb.group(
  FirstName:[value:'first name', disabled:true],
  LastValue:['last name,[Validators.required]]
)

以上示例将禁用FirstName 输入字段。

但是当您尝试通过这样的表单访问禁用的字段值时,就会出现真正的问题 console.log(this.form.value.FirstName); 并显示为 undefined 而不是打印字段的实际值。因此,要访问禁用字段的值,必须使用Reactive Forms 提供的getRawValue() 方法。即console.log(this.form.getRawValue().FirstName); 将打印表单字段的实际值,而不是未定义。

【讨论】:

getRawValue() - 哇,我的意思是这在文档中的位置。谢谢男人 - 这为我做了。我需要禁用输入,因为它具有预填充的值。我想将它们传递给 api 参数。在我使用 getRawValue() 之前我无法访问它们 - 谢谢!【参考方案11】:

这对我有用: this.form.get('first').disable(onlySelf: true);

【讨论】:

【参考方案12】:

最好的解决方案在这里:

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 数据后显示了我的大部分 FormControl,因此在使用 this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE) 为我的 formControl 设置/修补值之后,我显示了 formControl。当它传递给指令时,它显示 Cannot read property 'disable' of undefined【参考方案13】:

lastName: new FormControl(value: '', disabled: true, Validators.compose([Validators.required])),

【讨论】:

【参考方案14】:

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

在我的情况下,我必须在重新加载之前重置我的表单:

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

【讨论】:

【参考方案15】:

如果您有一个表单组,只需显示该表单组。然后所有的表单控件都被禁用。

formGroup = new FormGroup(
     firstName: new FormControl(''),
     lastName: new FormControl(''),
);
this.formGroup.disable();

【讨论】:

【参考方案16】:

我试图从本地存储中获取值,我希望禁用电子邮件和密码字段。这对我有用:

email: new FormControl(value: localStorage.getItem("email"), disabled:true,[
      Validators.required,
      Validators.minLength(3),
    ]),
password: new FormControl(value: localStorage.getItem("password"), disabled:true,[
      Validators.required,
      Validators.minLength(3),
    ])

【讨论】:

【参考方案17】:

使 reactive form angular 2+ 的字段disableenable

1.禁用

[attr.disabled]="true" 添加到输入。

&lt;input class="form-control" name="Firstname" formControlName="firstname" [attr.disabled]="true"&gt;

启用

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

启用整个表单

this.formname.enable();

单独启用特定字段

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

同为禁用,将 enable() 替换为 disable()。

这很好用。评论查询。

【讨论】:

【参考方案18】:

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

  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

【讨论】:

【参考方案19】:

在制作 ReactiveForm 时:[在 FormControl 中定义禁用的属性]

 'fieldName'= new FormControl(value:null,disabled:true)

html:

 <input type="text" aria-label="billNo" class="form-control" formControlName='fieldName'>

【讨论】:

这只是添加了与接受的答案相同的答案。它在这里没有增加任何新价值。【参考方案20】:

您可以通过添加一个 css 类并将其与 angular 绑定来轻松完成。

.disable
    pointer-events: none;
    <div [ngClass]="'disable': //condition goes here">
     <input type="text" formControlName="test">
     </div>

【讨论】:

以上是关于禁用反应形式的输入字段的主要内容,如果未能解决你的问题,请参考以下文章

使用反应钩子形式进行条件验证

如何使用模型驱动/反应形式修改指令中的输入值

禁用与状态相关的整个表单元素。反应

反应形式的输入/离子输入 - ChangeDetectionStrategy 的问题

订阅多个字段的 valueChanges 导致反应形式 angular 2 的性能问题

如何在Angular2中使禁用的反应形式可编辑