Javascript 以正确的方式禁用 Angular 5 输入字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50220643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:34:38  来源:igfitidea点击:

Disable Angular 5 Input fields correct way

javascripthtmlangularangular-forms

提问by Jo?o Ghignatti

I have a FormGroup that was created like that:

我有一个像这样创建的 FormGroup:

form: FormGroup;

constructor(private _formBuilder: FormBuilder) { }

this.form = this._formBuilder.group({
  name: ['', Validators.required],
  email: ['', Validators.required, Validators.email]
});

When an event occurs I want to disable those inputs, so, in the HTML I added:

当事件发生时,我想禁用这些输入,因此,在我添加的 HTML 中:

<input class="form-control" placeholder="Name" name="name" formControlName="name" [(ngModel)]="name" autocomplete="off" [disabled]="isDisabled" required>

<input class="form-control" placeholder="Email" name="email" formControlName="email" [(ngModel)]="email" email="true" autocomplete="off" [disabled]="isDisabled" required>

Where isDisabledis a variable I toggle to truewhen the said event happens.

As you can imagine, I get the message:

当所述事件发生时,isDisabled我切换到的变量在哪里true

你可以想象,我得到了这样的信息:

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.

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

看起来您正在将 disabled 属性与响应式表单指令一起使用。如果在组件类中设置此控件时将 disabled 设置为 true,则实际上会在 DOM 中为您设置 disabled 属性。我们建议使用这种方法来避免“检查后更改”错误。

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

So, with the example this warning shows and with a little search I found that I should declare my controls like:

因此,通过此警告显示的示例,通过一些搜索,我发现我应该声明我的控件,如:

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

The problem is: It is not toggling between disabled/enabled when the variable changes between true/false

How is the correct way of having a variable controlling if an input is enabled or disabled?

问题是:当变量在true/之间变化时,它不会在禁用/启用之间切换/false

如何让变量控制输入是启用还是禁用的正确方法?

I don't want to do it manually (ex: this.form.controls['name'].disable()) because it doesn't seems a very reactive way, I would have to call it inside a good amount of methods. Probably not a good practice.

我不想手动执行(例如:),this.form.controls['name'].disable()因为它似乎不是一种非常被动的方式,我必须在大量方法中调用它。可能不是一个好习惯。

Thx

谢谢

采纳答案by Bruno Silva

You can change the assignment of the variable to a setter method so that you'd have:

您可以将变量的分配更改为 setter 方法,以便您拥有:

set isDisabled(value: boolean) {
 this._isDisabled = value;
 if(value) {
  this.form.controls['name'].disable();
 } else {
    this.form.controls['name'].enable();
  }
}

回答by Reza

One solution is creating a directive and using binding for that as described in here

一种解决方案是创建一个指令并使用此处所述的绑定

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

}

then

然后

<input class="form-control" placeholder="Name" name="name" formControlName="name" autocomplete="off" [disableControl]="isDisabled" required>

NOTE:

笔记:

Doesn't work with Ivy

不适用于常春藤

回答by Rahul Seth



Disable TextBox in Angular 7

在 Angular 7 中禁用文本框

<div class="center-content tp-spce-hdr">
  <div class="container">
    <div class="row mx-0 mt-4">
      <div class="col-12" style="padding-right: 700px;" >
          <div class="form-group">
              <label>Email</label>
                <input [disabled]="true" type="text" id="email" name="email" 
                [(ngModel)]="email" class="form-control">
          </div>
     </div>
   </div>
 </div>

回答by Sandra Willford

The proper way to disable an form control. With reactive forms you should never disable an input from the template. So in whatever method in your component you are calling you should disable the input like this:

禁用表单控件的正确方法。对于反应式表单,您永远不应该禁用模板中的输入。因此,在您调用的组件中的任何方法中,您都应该像这样禁用输入:

this.form.get('name').disable();

回答by Aqeel Bahoo

In Reactive Form you can disable all form fields by this.form.disable(). In Template Driven Form you can disable all form fields by this.myform.form.disable()where myForm is @ViewChild('form') myForm;

在响应式表单中,您可以通过 禁用所有表单字段this.form.disable()。在模板驱动的表单中,您可以通过this.myform.form.disable()myForm 所在的位置禁用所有表单字段@ViewChild('form') myForm

回答by Joe Code

Not the clean or dry'st I imagine. Bu I tried the "set method" and didn't work out of the box...

不是我想象的干净或干燥。但是我尝试了“设置方法”并且没有开箱即用......

Needed some refactoring () => {simpleVersion} (hope it helps someone)

需要一些重构 () => {simpleVersion}(希望对某人有帮助)

component.ts

组件.ts

...
  // standard stuff...
  form: FormGroup;
  isEditing = false;
...
  // build the form...
  buildForm() {
    this.form = this.FormBuilder.group({
      key: [{value:'locked', disabled: !this.isEditing}],
      name: [],
      item: [],
      active: [false]
    })
  }
  // map the controls to "this" object
  // => i.e. now you can refer to the controls directly (ex. this.yourControlName)
  get key() { return <FormControl>this.form.get('key') }
  get name() { return <FormControl>this.form.get('name') }
...
  // ----------------------------------------
  //     THE GRAND FINALé - disable entire form or individual controls
  // ----------------------------------------
  toggleEdit() {
    if(!this.isEditing) {
      this.key.enable();      // controls
      this.name.enable();
      // this.form.enable();     // the form

      this.isEditing = !this.isEditing;
    } else {
      this.key.disable();      // the controls
      this.name.disable();     // the controls

      // this.form.disable();     // or the entire form

      this.isEditing = !this.isEditing;
    }
   }

& perhaps overkill on the HTML logic, so hope you find the bonus integrated ngClass toggle just as helpful.

并且可能对 HTML 逻辑有点矫枉过正,所以希望你发现额外的集成 ngClass 切换同样有帮助。

component.html (toggle button)

component.html(切换按钮)

<div class="btn-group" (click)="toggleEdit()">
           <label
             class="btn"
             role="button"
             [ngClass]="{'btn-success': isEditing,
                         'btn-warning': !isEditing}">toggle edit
           </label>
</div>

回答by Salim Hamidi

For input use [readonly] rather than [disabled] and it'll work

对于输入使用 [readonly] 而不是 [disabled] 它将起作用

回答by ldgorman

I have a function that enables a control on click.

我有一个功能可以在单击时启用控件。

  controlClick(control: any) {
      this.form.controls[control.ngControl.name].enable();
  }

Originally i was using

最初我正在使用

  control.disabled = false;

But this did not work for controls with <input>for example in my mat-chip-list.

但这不适用于控件,<input>例如在我的mat-chip-list.

I use FormGroup and disable each control in the constructor

我使用 FormGroup 并禁用构造函数中的每个控件

  constructor(
    private fb: FormBuilder,
    private dialogRef: MatDialogRef<EditDialogComponent>,
    @Inject(MAT_DIALOG_DATA) data
  ) {
    this.data = data;
    this.multiEdit = data.multiSelect;

    this.form = new FormGroup({
      autoArchive: new FormControl({
        value:
          this.getPreFill(data.selectedPolicy.autoArchive, this.multiEdit),
        disabled: true
        /*, Validators.required*/
      }),

...

...

  <mat-form-field (click)="controlClick(retrieveChipList)">
      <mat-chip-list #retrieveChipList formControlName="retrieveChipList">
        <mat-chip
        *ngFor="let email of data.selectedPolicy.retrieveEmailsToBeNotified" 
          (removed)="remove(email)" [selectable]="selectable"
          [removable]="removable" 
        >
          {{ email }}
          <mat-icon matChipRemove>cancel</mat-icon>
        </mat-chip>
        <input
        placeholder="Retrieve Emails to be Notified" 
        formControlName="retrieveChipList"
          [matChipInputFor]="retrieveChipList"
          [matChipInputAddOnBlur]="true"
          [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
          (matChipInputTokenEnd)="addRetrieveEmails($event)"
        />
      </mat-chip-list>
    </mat-form-field>

回答by Pu ChengLie

You can use this code on your ts file.

您可以在 ts 文件中使用此代码。

All controls:

所有控件:

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

Some controls

一些控件

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

Or Initial set method.

或初始设置方法。

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