我正在开发一个管理货币的表单,其中包含代码和标签字段。我正在使用最新的 Angular 功能并尝试利用键入的表单。
我在
FormArray
内有一个 FormGroup
,其中填充了一些预填充的货币数据。反应式表单按预期工作 - 我可以使用按钮添加和删除货币。
但是,当我尝试访问 HTML 模板中的表单控件属性以应用验证类(例如,显示输入字段的有效或无效状态)时,我遇到了问题。我收到以下错误:
NG9: Property 'code' does not exist on type 'AbstractControl<any, any>'. [plugin angular-compiler]
src/app/countries.component.html:34:58:
34 │ [class.is-valid]="currency.code.valid"
问题:
这是触发错误的代码:
[class.is-valid]="currency.code.valid"
我也尝试过将其更改为:
[class.is-valid]="currency.controls['code'].valid"
或者:
[class.is-valid]="currency.get('code').valid"
但我仍然遇到同样的错误。
我的打字稿代码:
import { CommonModule } from '@angular/common';
import { Component, inject, OnInit } from '@angular/core';
import {
FormArray,
FormBuilder,
FormGroup,
ReactiveFormsModule,
Validators
} from '@angular/forms';
export interface Item {
code: string;
label: string;
}
@Component({
selector: 'app-countries',
standalone: true,
imports: [ReactiveFormsModule, CommonModule],
templateUrl: './countries.component.html',
styleUrl: './countries.component.scss'
})
export class CountriesComponent {
currencyForm: FormGroup;
private formBuilder = inject(FormBuilder);
constructor() {
this.currencyForm = this.formBuilder.group({
currencies: this.formBuilder.array<FormGroup>(
[
{code: 'CAD', label: 'Canadian Dollar'},
{code: 'USD', label: 'United States Dollar'},
{code: 'EUR', label: 'Euro'}
].map(currency => this.createCurrencyFormGroup(currency))
)
});
}
createCurrencyFormGroup(currency: Item) {
return this.formBuilder.group({
code: [currency.code, [Validators.required, Validators.maxLength(3), Validators.minLength(3)]],
label: [currency.label, Validators.required]
});
}
get currencies(): FormArray {
return this.currencyForm.get('currencies') as FormArray;
}
addCurrency() {
const currencyControl = this.createCurrencyFormGroup({code: '', label: ''});
this.currencies.push(currencyControl);
}
removeCurrency(index: number) {
this.currencies.removeAt(index);
}
}
我的 HTML 代码:
<div class="container mt-3">
<form [formGroup]="currencyForm" class="row g-3">
<div class="col-md-5" formArrayName="currencies">
<button type="button" class="btn btn-sm btn-secondary" (click)="addCurrency()">Add Currency</button>
<div *ngFor="let currency of currencies.controls; let idx = index" [formGroupName]="idx">
<div class="row">
<div class="col-4">
<input type="text"
class="form-control"
placeholder="Currency Code"
formControlName="code"
maxlength="3"
[class.is-valid]="currency.get('code').valid"
[class.is-invalid]="currency.get('code').invalid" />
</div>
<div class="col-6">
<input type="text"
class="form-control"
placeholder="Currency Label"
formControlName="label"
[class.is-valid]="currency.get('label').valid"
[class.is-invalid]="currency.get('label').invalid" />
</div>
<div class="col-2">
<button type="button" class="btn btn-danger" (click)="removeCurrency(idx)">Remove</button>
</div>
</div>
</div>
</div>
</form>
</div>
我尝试过的:
currency.code.valid
、currency.controls['code'].valid
和 currency.get('code').valid
访问控件,但两者都会导致相同的错误。问题:
如何正确访问
FormArray
中的表单控件属性以在模板中应用验证类?我访问 code
和 label
属性的方法做错了什么?
非常感谢你
在我的演示中无法使用
currency.get('code')!.valid
重现错误,可能是由于我的 tsconfig.json 中的严格类型检查未启用
但是,您可以实现按位置从
FormGroup
currencies
获取指定 FormArray
的功能。这应该可以防止编译器抱怨提到的类型错误。
getCurrencyFormGroupByIndex(idx: number) {
return this.currencies.at(idx) as FormGroup;
}
<input
type="text"
class="form-control"
placeholder="Currency Code"
formControlName="code"
maxlength="3"
[class.is-valid]="getCurrencyFormGroupByIndex(idx).get('code')!.valid"
[class.is-invalid]="getCurrencyFormGroupByIndex(idx).get('code')!.invalid"
/>
<input
type="text"
class="form-control"
placeholder="Currency Label"
formControlName="label"
[class.is-valid]="getCurrencyFormGroupByIndex(idx).get('label')!.valid"
[class.is-invalid]="getCurrencyFormGroupByIndex(idx).get('label')!.invalid"
/>