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
Disable Angular 5 Input fields correct way
提问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)

