Angular FormArray 没有像我预期的那样工作

Angular FormArray not working as I expect

我希望你能帮我解决这个问题。 我有一个允许我动态添加项目到数组的表单,如果我们正在编辑并且看起来像这样,可以预先填充数组:

<mat-list class="hall-list"
    *ngIf="f.halls.length">
    <mat-list-item *ngFor="let hall of f.halls.controls;">
        <ng-container [formGroup]="hall">
            <img [src]="hall.url"
                matListAvatar />

            <p matLine>{{ hall.url }}</p>
            <p matLine>{{ hall.startTime }}</p>

            <p matLine>
                <mat-form-field class="full-width-field">
                    <mat-label for="url">Start time *</mat-label>
                    <input matInput
                        placeholder="Enter the start time"
                        formControlName="startTime">
                </mat-form-field>
            </p>
        </ng-container>
    </mat-list-item>
</mat-list>

如您所见,我正在尝试显示基于 "hall" 的 url 的图像。 我已将其设置如下:

ngOnInit() {
  this.buildForm();
  this.getHall();
}

get f() {
  return this.form.controls;
}

private buildForm(): void {
  this.form = this.formBuilder.group({
    videoUrl: ["", Validators.required],
    tags: ["", Validators.required],
    halls: this.formBuilder.array([])
  });
}

private getHall(): void {
  this.querySubscription = this.route.queryParams.subscribe(params => {
    const id = params.hallId || 0;
    const halls = this.form.controls.halls as FormArray;

    if (id) {
      this.hallService.get(id, "Videos").subscribe(hall => {
        const group = new FormGroup({
          id: new FormControl(hall.id),
          url: new FormControl(hall.url, Validators.required),
          startTime: new FormControl("", Validators.required)
        });
        halls.push(group);
      });
    }
  });
}

但是当我查看我的页面时,虽然没有出现任何错误,但它不显示图像。我添加了 <p matLine> 来尝试调试,但它们也是空的。 有谁知道我做错了什么?

只是因为有些人在陈述错误,这里是总的 html 文件:

<form [formGroup]="form"
    (ngSubmit)="save(form.value)"
    novalidate>

    <app-stepper #stepper>
        <app-step name="Video"
            [expanded]="stepper.step === 0">

            <mat-form-field class="full-width-field">
                <mat-label for="videoUrl">Youtube link *</mat-label>
                <input matInput
                    placeholder="Enter a valid image url"
                    formControlName="videoUrl">
            </mat-form-field>

            <app-tags (change)="onChangeTags($event)"></app-tags>

            <mat-action-row>
                <button mat-raised-button
                    type="button"
                    color="primary"
                    (click)="getSnippet()"
                    [disabled]="!f.videoUrl.valid || !f.tags.valid">Next</button>
            </mat-action-row>
        </app-step>

        <app-step name="Halls"
            [expanded]="stepper.step === 1"
            [disabled]="stepper.step < 1">

            <p>Chanell: {{ model?.channelTitle }}</p>
            <p>Title: {{ model?.title }}</p>

            <mat-list class="hall-list"
                *ngIf="f.halls.length">
                <div formArrayName="halls">
                    <mat-list-item *ngFor="let hall of f.halls.controls;">
                        <ng-container [formGroup]="hall">
                            <img [src]="hall.url"
                                matListAvatar />

                            <p matLine>{{ hall.url }}</p>
                            <p matLine>{{ hall.startTime }}</p>

                            <p matLine>
                                <mat-form-field class="full-width-field">
                                    <mat-label for="url">Start time *</mat-label>
                                    <input matInput
                                        placeholder="Enter the start time"
                                        formControlName="startTime">
                                </mat-form-field>
                            </p>
                        </ng-container>
                    </mat-list-item>
                </div>
            </mat-list>

            <app-image-previewer [files]="files"
                [urls]="urls"
                [progress]="progress"></app-image-previewer>

            <mat-action-row>
                <app-file [files]="files"
                    [urls]="urls"></app-file>
                <button mat-raised-button
                    type="submit"
                    color="primary"
                    [disabled]="!form.valid || !f.halls.length">Save</button>
            </mat-action-row>

        </app-step>
    </app-stepper>
</form>

这是一个显示问题的 stackblitz:https://angular6-dynamic-form-array-vnnye9.stackblitz.io

你应该使用 formArrayName

<mat-list class="hall-list"
    *ngIf="f.halls.length">
    <div formArrayName="halls"> 
    <mat-list-item *ngFor="let hall of f.halls.controls;">
        <ng-container [formGroup]="hall">
            <img [src]="hall.url"
                matListAvatar />

            <p matLine>{{ hall.url }}</p>
            <p matLine>{{ hall.startTime }}</p>

            <p matLine>
                <mat-form-field class="full-width-field">
                    <mat-label for="url">Start time *</mat-label>
                    <input matInput
                        placeholder="Enter the start time"
                        formControlName="startTime">
                </mat-form-field>
            </p>
        </ng-container>
    </div>
    </mat-list-item>
</mat-list>

可能出现的问题:

  1. hall.url 应该是 hall.value.url.
  2. formArrayName下的[formGroup]应该是循环的索引f.halls.controls。

在您的 html 文件中:

<mat-list class="hall-list" *ngIf="f.halls.length">
    <div formArrayName="halls"> 
        <mat-list-item *ngFor="let hall of f.halls.controls; index as i">
            <ng-container [formGroup]="i">
                <img [src]="hall.value.url"
                matListAvatar />

                <p matLine>{{ hall.value.url }}</p>
                <p matLine>{{ hall.value.startTime }}</p>

                <p matLine>
                    <mat-form-field class="full-width-field">
                        <mat-label for="url">Start time *</mat-label>
                        <input matInput
                            placeholder="Enter the start time"
                            formControlName="startTime">
                    </mat-form-field>
                </p>
            </ng-container>
        </mat-list-item>
    </div>
</mat-list>

参考您提供的最新stackblitz代码,图像src的值为空,您可以使用从表单组到数​​组级别的引用以及每个索引设置该值,如myForm.value.arr[i].url..

因此

改变,

<div><img [src]="url" alt="some url" /></div>

收件人:

 <div><img [src]="myForm.value.arr[i].url" alt="some url" /></div>

更改原因:

您正在迭代一个数组以显示 url,它没有任何值,因此它给出 null..

大家可以看看下图,

这里通常用于检索我们使用的表单值,{{myForm.value | json}} 将给出表单值的 json 格式,因此使用它您需要找出 url 的确切位置谎言,那么你就可以找到路径。

所以在你的情况下它可以在这里 myForm.value.arr[i].url.. 我们需要从表单级对象访问它到索引数组然后是该项目的 url。

Working Stackblitz Here