如何以编程方式将属性设置为 FormControl?
How to set attribute to FormControl programmatically?
简短的大问题: 基本上我想要实现的是,将 readonly
属性应用于 FormControl
(文本框),就在以编程方式创建它时.
完整场景:
我有一个 Form
,它有一个 FormRow
,其元素 (FormGroup
s) 是部分动态生成的。我还提供了一个选项,可以在单击按钮时附加一行。
我希望动态生成的 FormGroup
的 FormControl
(文本框)是 readonly
,但手动添加的 FormControl
应该是可编辑的。
我怎样才能做到这一点?
<div formArrayName="rows">
<div class="row" *ngFor="let row of detailForm.get('rows').controls; let i = index" [formGroupName]="i">
<div class="col-xs-1 text-center">
<input type="checkbox" [(ngModel)]="detailSelected[i]" [ngModelOptions]="{standalone: true}">
</div>
<div class="col-xs-2">
<input type="text" class="form-control" formControlName="account" (change)="getAccountAssociatedDetails(detailForm.get(['rows', i, 'account']), 'account', i)">
</div>
<div class="col-xs-2">
<input type="text" class="form-control" formControlName="detailNo" (change)="getAccountAssociatedDetails(detailForm.get(['rows', i, 'detailNo']), 'detail', i)">
</div>
<div class="col-xs-4">
<input type="text" class="form-control" readonly formControlName="detailName">
</div>
<div class="col-xs-3">
<input type="text" class="form-control" readonly formControlName="detailCountry">
</div>
</div>
</div>
在文本框值 change
上,我正在调用函数 getAccountAssociatedDetails
,如您所见。如果有一些与输入的值相关的详细信息,我将替换当前的 FormGroup
并向该行添加更多 FormGroup
s。
getAccountAssociatedDetails(control: FormControl, type: string, index: number) {
let value = control.value;
if (!!value) {
let form = this.detailForm;
control.setErrors({
'alreadyEntered': null
});
if (type === 'detail') {
if (this.detailAlreadyEnteredManually.detailNo.includes(value)) {
control.setErrors({
'alreadyEntered': true
});
}
} else if (type === 'account') {
if (this.detailAlreadyEnteredManually.accountNumber.includes(value)) {
control.setErrors({
'alreadyEntered': true
});
}
}
// if detail or account is already entered dont call service
if (!control.hasError('alreadyEntered')) {
this.agreementDetailsService.getdetails(value, type)
.subscribe(response => {
let associatedDetailsArray = < Array < any >> response;
if (!!associatedDetailsArray) {
let rows = < FormArray > form.get('rows');
// if search mode is 'detail'
if (type === 'detail') {
if (!this.detailAlreadyEnteredManually.detailNo.includes(value)) {
rows.setControl(index, this.builddetailItem(associatedDetailsArray[0].accountNumber.value, value, associatedDetailsArray[0].detailName, associatedDetailsArray[0].detailCountry));
this.detailAlreadyEnteredManually.detailNo.push(value);
for (let i = 1; i < associatedDetailsArray.length; i++)
rows.insert(index + i, this.builddetailItem(associatedDetailsArray[i].accountNumber.value, value, associatedDetailsArray[i].detailName, associatedDetailsArray[i].detailCountry));
}
//if search mode is 'account'
} else if (type === 'account') {
if (!this.detailAlreadyEnteredManually.accountNumber.includes(value)) {
rows.setControl(index, this.builddetailItem(value, associatedDetailsArray[0].detailNo.value, associatedDetailsArray[0].detailName, associatedDetailsArray[0].detailCountry));
this.detailAlreadyEnteredManually.accountNumber.push(value);
for (let i = 1; i < associatedDetailsArray.length; i++)
rows.insert(index + i, this.builddetailItem(value, associatedDetailsArray[i].detailNo.value, associatedDetailsArray[i].detailName, associatedDetailsArray[i].detailCountry));
}
}
}
},
error => console.log(error));
}
}
}
FormGroup
中的最后两个字段默认为 readonly
。一旦用户在前两个字段中的任何一个输入内容并聚焦,就应该获取与该值相关的详细信息,替换当前的 FormGroup
并附加生成列表中的其他 FormGroup
。我希望那些新添加的 FormGroup
中的所有 FormControl
都应该是 readonly
。用户可以添加更多字段并重复该过程。
据此:https://github.com/angular/angular/issues/11447,无法在表单控件上添加 readonly
,仅支持 disabled
。
我什至更喜欢 disabled
,因为它在视觉上(灰色)显示用户无法触摸它。所以当你想禁用你的表单控件时,你只需使用:
formControlNameHere.disable();
或者如果您需要禁用整个表单组,您可以使用
以相同的方式进行
myFormGroupNameHere.disable()
我们需要记住的是,此表单控件随后从表单对象中排除。要获取所有禁用的值,您需要调用:
this.myForm.getRawValue();
如果您确实想添加 readonly
,则需要对其进行一些变通::
[readonly]="anyBooleanPropertyFromComponent"
当然在那个答案中我们使用了一个布尔值,这当然对你不起作用,然后我看到你需要设置一个额外的布尔 formcontrol,然后你可以用 [readonly]
。但这只是在您的表单组中添加一个新的 "unnecessary" 属性,所以使用 disabled
的另一个原因 :)
希望对您有所帮助!
简短的大问题: 基本上我想要实现的是,将 readonly
属性应用于 FormControl
(文本框),就在以编程方式创建它时.
完整场景:
我有一个 Form
,它有一个 FormRow
,其元素 (FormGroup
s) 是部分动态生成的。我还提供了一个选项,可以在单击按钮时附加一行。
我希望动态生成的 FormGroup
的 FormControl
(文本框)是 readonly
,但手动添加的 FormControl
应该是可编辑的。
我怎样才能做到这一点?
<div formArrayName="rows">
<div class="row" *ngFor="let row of detailForm.get('rows').controls; let i = index" [formGroupName]="i">
<div class="col-xs-1 text-center">
<input type="checkbox" [(ngModel)]="detailSelected[i]" [ngModelOptions]="{standalone: true}">
</div>
<div class="col-xs-2">
<input type="text" class="form-control" formControlName="account" (change)="getAccountAssociatedDetails(detailForm.get(['rows', i, 'account']), 'account', i)">
</div>
<div class="col-xs-2">
<input type="text" class="form-control" formControlName="detailNo" (change)="getAccountAssociatedDetails(detailForm.get(['rows', i, 'detailNo']), 'detail', i)">
</div>
<div class="col-xs-4">
<input type="text" class="form-control" readonly formControlName="detailName">
</div>
<div class="col-xs-3">
<input type="text" class="form-control" readonly formControlName="detailCountry">
</div>
</div>
</div>
在文本框值 change
上,我正在调用函数 getAccountAssociatedDetails
,如您所见。如果有一些与输入的值相关的详细信息,我将替换当前的 FormGroup
并向该行添加更多 FormGroup
s。
getAccountAssociatedDetails(control: FormControl, type: string, index: number) {
let value = control.value;
if (!!value) {
let form = this.detailForm;
control.setErrors({
'alreadyEntered': null
});
if (type === 'detail') {
if (this.detailAlreadyEnteredManually.detailNo.includes(value)) {
control.setErrors({
'alreadyEntered': true
});
}
} else if (type === 'account') {
if (this.detailAlreadyEnteredManually.accountNumber.includes(value)) {
control.setErrors({
'alreadyEntered': true
});
}
}
// if detail or account is already entered dont call service
if (!control.hasError('alreadyEntered')) {
this.agreementDetailsService.getdetails(value, type)
.subscribe(response => {
let associatedDetailsArray = < Array < any >> response;
if (!!associatedDetailsArray) {
let rows = < FormArray > form.get('rows');
// if search mode is 'detail'
if (type === 'detail') {
if (!this.detailAlreadyEnteredManually.detailNo.includes(value)) {
rows.setControl(index, this.builddetailItem(associatedDetailsArray[0].accountNumber.value, value, associatedDetailsArray[0].detailName, associatedDetailsArray[0].detailCountry));
this.detailAlreadyEnteredManually.detailNo.push(value);
for (let i = 1; i < associatedDetailsArray.length; i++)
rows.insert(index + i, this.builddetailItem(associatedDetailsArray[i].accountNumber.value, value, associatedDetailsArray[i].detailName, associatedDetailsArray[i].detailCountry));
}
//if search mode is 'account'
} else if (type === 'account') {
if (!this.detailAlreadyEnteredManually.accountNumber.includes(value)) {
rows.setControl(index, this.builddetailItem(value, associatedDetailsArray[0].detailNo.value, associatedDetailsArray[0].detailName, associatedDetailsArray[0].detailCountry));
this.detailAlreadyEnteredManually.accountNumber.push(value);
for (let i = 1; i < associatedDetailsArray.length; i++)
rows.insert(index + i, this.builddetailItem(value, associatedDetailsArray[i].detailNo.value, associatedDetailsArray[i].detailName, associatedDetailsArray[i].detailCountry));
}
}
}
},
error => console.log(error));
}
}
}
FormGroup
中的最后两个字段默认为 readonly
。一旦用户在前两个字段中的任何一个输入内容并聚焦,就应该获取与该值相关的详细信息,替换当前的 FormGroup
并附加生成列表中的其他 FormGroup
。我希望那些新添加的 FormGroup
中的所有 FormControl
都应该是 readonly
。用户可以添加更多字段并重复该过程。
据此:https://github.com/angular/angular/issues/11447,无法在表单控件上添加 readonly
,仅支持 disabled
。
我什至更喜欢 disabled
,因为它在视觉上(灰色)显示用户无法触摸它。所以当你想禁用你的表单控件时,你只需使用:
formControlNameHere.disable();
或者如果您需要禁用整个表单组,您可以使用
以相同的方式进行myFormGroupNameHere.disable()
我们需要记住的是,此表单控件随后从表单对象中排除。要获取所有禁用的值,您需要调用:
this.myForm.getRawValue();
如果您确实想添加 readonly
,则需要对其进行一些变通::
[readonly]="anyBooleanPropertyFromComponent"
当然在那个答案中我们使用了一个布尔值,这当然对你不起作用,然后我看到你需要设置一个额外的布尔 formcontrol,然后你可以用 [readonly]
。但这只是在您的表单组中添加一个新的 "unnecessary" 属性,所以使用 disabled
的另一个原因 :)
希望对您有所帮助!