Angular 6如何使表单中所有输入元素都不可编辑

17

有没有一种方法可以通过在 Angular / Angular-material 中仅指定父 div 名称的方式来禁用和使表单中的所有字段(包括 input / mat-select / textfield / option/input/mat-checkbox 等)都不可编辑?

@Component({
  templateUrl: './leaseholder.component.html'
})
export class LeaseholderComponent implements OnInit, IFormDirtyWarningComponent {

  leaseholderForm: FormGroup;

  constructor(private router: Router, private formBuilder: FormBuilder) {
    this.createLeaseholderForm();
  }

  createLeaseholderForm() {
    this.leaseholderForm = this.formBuilder.group({
      civility: [this.identityModel.civility],
      firstName: [this.identityModel.firstName, Validators.compose([Validators.pattern("[^\\d]+")])],
      lastName: [this.identityModel.lastName, Validators.compose([Validators.pattern("[^\\d]+")])],
      birthName: [this.identityModel.birthName, Validators.compose([Validators.pattern("[^\\d]+")])],
      birthDate: [this.identityModel.birthDate],
      birthPlace: [this.identityModel.birthPlace, Validators.compose([Validators.pattern("[^\\d]+")])],
      nationality: ['FR', this.identityModel.nationality],
      endOfStay: [this.identityModel.endOfStay]
    });
  }

    <form [formGroup]="leaseholderForm" (ngSubmit)="onSubmit()">
                <div class="mat-radio-group-inverted">
                    <mat-radio-group formControlName="civility">
                        <mat-radio-button color="primary" value="MR">M.</mat-radio-button>
                        <mat-radio-button color="primary" value="MME">MME.</mat-radio-button>
                    </mat-radio-group>
                </div>
                <mat-form-field>
                    <input matInput upperCaseInput placeholder="Nom d'usage" formControlName="lastName">
                </mat-form-field>
...........................
..........  example
    </form>
7个回答

33

禁用和只读并不完全相同。禁用的输入框当然也是不可编辑的,但它具有明显的外观——变灰色且看起来“已禁用”。只读的输入框与普通输入框外观相同,但无法编辑。因此,您需要考虑您想要的控件实际上是禁用还是只读。

如果您只想使用只读功能,可以简单地在<input>元素中使用readonly属性,并将其绑定到控制器中的变量。例如:

export class LeaseholderComponent implements OnInit, IFormDirtyWarningComponent {

    @Input() editable: boolean = false; // doesn't have to be an @Input
    ...
}

<form [formGroup]="leaseholderForm" (ngSubmit)="onSubmit()">
    <mat-form-field>
        <input matInput [readonly]="!editable" upperCaseInput placeholder="Nom d'usage" formControlName="lastName">
    </mat-form-field>
    ...
</form>
请注意,editable属性不需要是一个@Input,但如果您将表单用作可重复使用的组件并且需要在DOM级别上进行可编辑/只读决策,则可能会有用。 对于其他组件(如单选按钮),其中没有readonly属性可用,您应该重新考虑布局。在只读模式下显示单选选项列表可能没有意义,更好的选择是使用不同的组件来显示单选选项。例如,使用标签和值对:
<div *ngIf="editable; else readonlyRadio" class="mat-radio-group-inverted">
    <mat-radio-group formControlName="civility">
        <mat-radio-button color="primary" value="MR">M.</mat-radio-button>
        <mat-radio-button color="primary" value="MME">MME.</mat-radio-button>
    </mat-radio-group>
</div>
<div #readonlyRadio>
    <label>Civility</label>
    <span>{{ leaseholderForm.controls['civility'].value }}</span>
</div>

2
这是最佳解决方案,因为它不会将字段标记为无效。 - Gabb1995

25

如果您正在使用响应式表单,可以通过逐一处理途径来以编程方式实现此操作:

 this.formGroupName.controls[controlNmae].disable();

例如:this.formGroupName.controls['lastName'].disable()

要一次性禁用所有内容:

this.formGroupName.disable()

在您的情况下,请执行:this.leaseholderForm.disable()
要重新启用它,请执行:this.leaseholderForm.enable()

您可以创建一个类似以下函数的函数,并在调用createLeaseholderForm()之后调用它:

disableForm() {
 this.leaseholderForm.disable()
}  

了解更多信息,请阅读此文


1
我同意。这应该可以工作,就像这里所示。@AnouarMokhtari - 控制台没有错误吗? - ConnorsFan
4
请记住,禁用的<input>不会随表单提交,但只读的<input>会随表单一起提交。 - JWess
1
太好了!这正是我需要的!谢谢! - dmarquina

9

因为某些组件上无法使用 disabled 属性,所以我在 css 中设置了 pointer-events:none 来覆盖 div 内容中的所有组件。

以下是我的 CSS 代码:

.disabledDiv {
      pointer-events: none;
      opacity: 0.4;   }

这是我的HTML代码:

<div class="content-area" [ngClass]="{disabledDiv: !isActiveDiv}"> 
    <!-- other components here (input/select/etc.) -->
<div> 
在我的TS上:
editData() {
    this.isActiveDiv = true;
  }

不熟悉指针事件。但这是否也会阻止制表键? - Ian Grainger

1
this.formGroupName.controls['lastName'].disable()
在Angular 8中对我无效。因此,我通过在HTML内添加'readonly'属性,然后在.ts文件中更改其值来使其工作。 在.html文件内:
 <input formControlName="email" matInput type="email" #email email="true" [readonly]="email_readonly" />
在 .ts 文件内。
email_readonly = false;

yourFunction()
{
  this.email_readonly = true;
}

1

enter image description here

在输入标签内的HTML文件中使用readonly属性。

9
尽量不要使用代码图片回答问题——代码本身就是文本,为什么不直接贴出来呢? - ross

1

是的,我使用响应式表单,我更新了问题。.disable()不起作用。 - Anouar Mokhtari
你能提供你组件控制器的代码吗? - ggradnig
完成了,我不确定,.disable() 是否会使表单的所有字段都不可编辑,我认为它只是禁用表单中的一个控件。 - Anouar Mokhtari

1
在HTML模板中使用disable属性。
           <mat-form-field>
                <input matInput upperCaseInput placeholder="Nom d'usage" formControlName="lastName" disable>
            </mat-form-field>

1
在Angular响应式表单中,不应该使用disabled属性来禁用输入元素。相反,应该禁用表单控件:control = new FomrControl({'value', disabled: true}, [validators]); - G. Tranter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,