Angular Reactive Form - 如何将 FormArray 与 FormGroup(s) 一起使用

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

我正在尝试以我的反应形式模仿我的模型。我已经设置了一些 FormGroups 来“嵌套”根据我的模型有意义的东西。我在设置我的组件以 read 值时遇到问题——这表明我可能也没有正确设置我的模板。

取决于我是在编辑现有位置还是创建新位置,

@Input() location: ILocation;

可以是

undefined
。目前,我只专注于与现有地点合作,所以我知道
location
有价值。

// location.model.ts

name: string;
...
messaging: [
    {
        email: {
            fromName: string;
            fromAddress: string;
        };
    }
];
...
createdAt?: string;
updatedAt?: string;
deletedAt?: string;

在我的模板中,我使用

ngClass
给用户验证反馈:

// location.commponent.html

<div formGroupName="messaging">
    <div formGroupName="email">
        ...
        <div [ngClass]="form.get(['messaging', 'email', 'fromName'])!.errors && (form.get(['messaging', 'email', 'fromName'])!.dirty || form.get(['messaging', 'email', 'fromName'])!.touched) ? 'red' : 'green'">
            <input name="fromName"/>
        </div>
        <!-- fromAddress -->
    </div>
</div>

在我的组件中,我通过输入绑定传递模型,然后设置我的表单组和表单字段,如下所示:

// location.component.ts

@Input() location: ILocation; 

form: FormGroup;

...

ngOnInit(): void {
    this.form = new FormGroup({name: new FormControl(this.location.name, [Validators.required]),
    messaging: new FormGroup({
    email: new FormGroup({
        fromName: new FormControl(this.location.messaging[0].email.fromName, [Validators.required]),
        fromAddress: new FormControl(this.location.messaging[0].email.fromAddress, [Validators.required]),
        }),
    }),
}

我看到的错误是:

无法读取未定义的属性(读取“电子邮件”)

如果我注销组件中的内容:

console.log('messaging: ', this.location.messaging);

// email: {fromName: 'No Reply <[email protected]>', fromAddress: '[email protected]'}

我试过

messaging['email']
messaging.email
messaging[0]
的各种方法,但我找不到正确的路径。

我也不确定我是否在我的模板中正确使用了

get()
方法。

如何设置我的表单以正确读取/显示数据?

更新:

毫不奇怪,我遇到的一个大问题是发回错误形状的数据。

最后,这是我要创建的 JSON:

[{"email":{"fromName":"No Reply <[email protected]>","fromAddress":"[email protected]"}}]

看起来我需要使用 FormArray 来发送正确的形状:

messaging: new FormArray([
    new FormGroup({
        email: new FormGroup({
            fromName: new FormControl(this.location.messaging[0].email.fromName, [Validators.required]),
            fromAddress: new FormControl(this.location.messaging[0].email.fromAddress, [Validators.required]),
        }),
    }),
]),

这在我的模板中造成了一些麻烦,因为我目前正在这样做:

form.get('messaging[0].email.fromAddress')

结果:

错误:找不到路径为“消息 -> 电子邮件”的控件

我想我需要以某种方式循环

FormArray
。不过,这确实不是动态数组。我将永远拥有
email
,只有
fromName
fromAddress

angular typescript angular-reactive-forms formarray formgroups
1个回答
1
投票

是的,您需要

FormArray
,因为
messaging
是一个数组。

您需要通过

FormArray
迭代
*ngFor
中的每个元素并提供索引(
i
):

form.get(['messaging', i, 'email', 'fromName'])

从父 FormGroup 到 fromName

FormControl
的模板表单的完整
flow
将是:

form (

FormGroup
) --> messaging (
FormArray
) --> i (
FormGroup
) --> email (
FormGroup
) --> fromName (
FormControl
)

HTML 模板应该是:

<div [formGroup]="form">
  <div
    formArrayName="messaging"
    *ngFor="let control of messaging.controls; let i = index"
  >
    <ng-container [formGroupName]="i">
      <div formGroupName="email">
        ...
        <div
          [ngClass]="
            form.get(['messaging', i, 'email', 'fromName'])!.errors &&
            (form.get(['messaging', i, 'email', 'fromName'])!.dirty ||
              form.get(['messaging', i, 'email', 'fromName'])!.touched)
              ? 'red'
              : 'green'
          "
        >
          <input formControlName="fromName" />
        </div>
        <div>
          <!-- fromAddress -->
          <input formControlName="fromAddress" />
        </div>
      </div>
    </ng-container>
  </div>
</div>
get messaging(): FormArray {
  return this.form.get('messaging') as FormArray;
}

Demo @ StackBlitz

© www.soinside.com 2019 - 2024. All rights reserved.