从 HTML 模板中的 FormArray 访问 Angular 类型化表单属性

问题描述 投票:0回答:1

我正在开发一个管理货币的表单,其中包含代码和标签字段。我正在使用最新的 Angular 功能并尝试利用键入的表单。

我在

FormArray
内有一个
FormGroup
,其中填充了一些预填充的货币数据。反应式表单按预期工作 - 我可以使用按钮添加和删除货币。

Currency form working fine

但是,当我尝试访问 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
    访问控件,但两者都会导致相同的错误。
  • Angular 似乎无法在模板中以这种方式识别控件属性。

问题:

如何正确访问

FormArray
中的表单控件属性以在模板中应用验证类?我访问
code
label
属性的方法做错了什么?

非常感谢你

angular typescript multidimensional-array angular-forms
1个回答
0
投票

在我的演示中无法使用

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"
/>

演示@StackBlitz

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.