Angular FormArray не работает, как я ожидаю - PullRequest
0 голосов
/ 06 марта 2020

Я надеюсь, что вы можете помочь мне с этим. У меня есть форма, которая позволяет мне динамически добавлять элементы в массив, массив можно предварительно заполнить, если мы редактируем, и выглядит примерно так:

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

Как видите, я пытаюсь отобразить изображение на основе 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>

Вот фрагмент стека, показывающий проблему: https://angular6-dynamic-form-array-vnnye9.stackblitz.io

Ответы [ 3 ]

1 голос
/ 06 марта 2020

Возможные проблемы:

  1. hall.url должен быть hall.value.url.
  2. [formGroup] в formArrayName должно быть индексом цикла 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>
1 голос
/ 06 марта 2020

Применительно к последнему предоставленному вами коду стекаблиц значение изображения 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, который не имеет никакого значения, поэтому он дает ноль ..

Вы можете посмотреть на изображение ниже,

enter image description here

Здесь, как правило, для получения значений формы, которые мы используем, {{myForm.value | json}}, который даст формат json для значения формы, поэтому, используя его, вам нужно выяснить, где именно находится URL, тогда вы можете найти путь .

Так что здесь, в вашем случае, он доступен здесь myForm.value.arr[i].url .. Нам нужно получить к нему доступ из объекта уровня формы в массив с индексом, а затем URL этого элемента.

Здесь работает Stackblitz

0 голосов
/ 06 марта 2020

Вы должны использовать 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>
...