我在Angular组件中使用matInput
和mat-form-field
(@ angular / material),我无法禁用matInput
。
A working example can be seen here.
我似乎错过了一些明显的东西,但对于我的生活,我无法弄清楚是什么。这是一个错误吗?
如果我从[formControlName]
删除CustomFormInputComponent
,那么我可以成功停用matInput
CustomFormInputComponent
:
import { Input, Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'app-custom-form-input',
template: `
<mat-form-field [formGroup]="form">
<input matInput placeholder='Name' [formControlName]="formControlName" [disabled]='disabled'>
</mat-form-field>
`,
})
export class CustomFormInputComponent {
@Input() form: FormGroup;
@Input() formControlName: string = 'name';
@Input() disabled = false;
}
AppComponent
:
import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<p>At least one of these inputs should be disabled, but none are :(</p>
<app-custom-form-input [form]="form" [disabled]='true'></app-custom-form-input>
<app-custom-form-input [form]="form" [disabled]="'disabled'"></app-custom-form-input>
`,
})
export class AppComponent {
public form: any;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
name: ''
})
}
}
非常感谢任何见解!
有关David的答案的更多上下文:Angular根据被动表单控件的禁用状态更新DOM状态。我认为发生了什么:angular在CustomFormInputComponent
之前渲染AppComponent
并将组件渲染为禁用。然后渲染AppComponent,并在启用form
控件的情况下构建name
。然后Angular继续并取消禁用DOM输入元素(这是行为设计)。
答案 0 :(得分:14)
如果您使用的是FormGroup,则不应禁用HTML模板中的表单。如果您尝试与FormControl一起禁用HTML,它将无法工作。相反,它应该在FormGroup中完成。试试这个:
template: `
<mat-form-field [formGroup]="form">
<input matInput placeholder='Name' [formControlName]="formControlName">
</mat-form-field>
`
和
ngOnInit() {
this.form = this.fb.group({
name: new FormControl({ value: '', disabled: this.disabled })
});
}
同样......不是什么大不了但你真的应该这样做:
public form: FormGroup;
而不是:
public form: any;
不要忘记导入
import { FormGroup, FormControl } from '@angular/forms';
顺便说一句,表单组声明中的名称应该与您在HTML中设置的内容相匹配。 所以:
<input formControlName="myInputName">
和
this.form = this.fb.group({
myInputName....
});
答案 1 :(得分:1)
如果您使用的是材料,则可以添加
<mat-form-field [formGroup]="form">
<input matInput placeholder='Name' [formControlName]="formControlName" readOnly>
</mat-form-field>
答案 2 :(得分:0)
如果使用的是FormGroup,则必须使用禁用的属性来创建FormGroup / FormControl:
name: new FormControl({ value: '', disabled: this.disabled })
但是,如果要禁用/启用,可以在HTML中使用它:
<input type="text" formControlName="name" [attr.disabled]="isDisabled == true ? true : null" />
答案 3 :(得分:0)
我遇到了同样的问题,并使用* ngIf指令解决了它。如果应禁用输入,请将其禁用,删除其表单绑定并手动提供其值。如果不是,那么请照原样使用formControl。
这是您的模板:
<mat-form-field [formGroup]="form">
<input matInput placeholder='Name' [formControlName]="formControlName" [disabled]='disabled'>
</mat-form-field>
更改为:
<mat-form-field *ngIf="disabled">
<input matInput placeholder='Name' [value]="form.formControlName" disabled='true'>
</mat-form-field>
<mat-form-field *ngIf="!disabled" [formGroup]="form">
<input matInput placeholder='Name' [formControlName]="formControlName">
</mat-form-field>
答案 4 :(得分:0)
阅读本文的每个人都需要了解以下内容:
Disable() 方法将从中删除该值。调试您的表单组,看看当您在输入上使用 .disable() 时会发生什么。您仍将拥有 FormControl,但该特定输入的值将消失。使用 enable()/disable() 时查看 FormGroup.value。
上面的只读答案是迄今为止实现禁用仍需要值的输入的最简单方法
结合使用 readonly 和 ngIf/ng-templates,您将能够成功切换已禁用的输入,并仍能在表单中捕获它的值。
在 DOM 中禁用响应式表单并不能像您想象的那样工作。
在 FormControl 创建期间禁用输入时,是否将禁用的属性绑定到稍后将尝试操作的变量并不重要。它仅在创建时拍摄该属性值的快照,并将禁用设置为控件上的布尔值。尝试随意操作该值,控件已经创建,无需关心新值是什么。
使用上述只读答案和 ng-templates 的示例:
<div class="col-4">
<div *ngIf="hasVarHeight.checked else normalHeight">
<mat-form-field>
<mat-label>Height</mat-label>
<input
type="text"
matInput
[formControl]="heightCtrl"
[value]="'*'" readonly>
</mat-form-field>
</div>
<ng-template #normalHeight>
<mat-form-field>
<mat-label>Height</mat-label>
<input
type="text"
matInput
[formControl]="heightCtrl"
mask="separator.3"
thousandSeparator=","
[suffix]="unitCtrl.value === 'Metric' ? ' mm' : ' in'"
[placeholder]="unitCtrl.value === 'Metric' ? 'mm' : 'inches'"
[dropSpecialCharacters]="false">
<mat-error *ngIf="heightCtrl.hasError('required')">
Height is required
</mat-error>
</mat-form-field>
</ng-template>
</div>
</div>
<div class="form-row">
<div class="col-4">
<mat-checkbox
#hasVarHeight
(click)="makeVariable('height')"
name="varheight"
[formControl]="hasVarHeightCtrl">
Variable Height?
</mat-checkbox>
</div>
</div>
希望以上内容能让您了解如何使用只读和模板使表单更好,同时仍保留所需输入的掩码。您可以使用上面的 makeVariable() 之类的方法在只读输入上动态设置一个值,并向用户展示一些有用的东西。
只是一个想法。感谢您对 Yogesh 的只读回答。
答案 5 :(得分:-1)
<mat-form-field fxFlex>
<input matInput placeholder="No" formControlName="no" readonly>
</mat-form-field>
您是否尝试过只读选项。这对我来说很好。
工作代码: html:
<mat-form-field fxFlex>
<input matInput placeholder="No" formControlName="no" readonly>
</mat-form-field>
答案 6 :(得分:-2)
在html页面中:
<form [formGroup]="formForAddDSBData">
<mat-form-field class="form-element" >
<mat-icon matPrefix><i class="fa fa-address-card fa-1x"></i></mat-icon>
<input matInput disabled id="AreaAddress" formControlName="AreaAddress"
#Contact1 placeholder="Area/Address" type="text" >
<mat-error *ngIf="!formForAddDSBData.controls['AreaAddress'].valid &&
formForAddDSBData.controls['AreaAddress'].touched">
Area/Address is required
</mat-error>
</mat-form-field>
</form>
要禁用此垫输入,您需要在.ts文件中编写以下代码
this.formForAddDSBData.get("AreaAddress").disable();