【问题标题】:Angular Reactive Form: How to listen to changes in FormControls of a FormArrayAngular Reactive Form:如何监听 FormArray 的 FormControls 的变化
【发布时间】:2021-06-04 23:19:16
【问题描述】:

我正在使用 Angular v11.2.3 和 vTypeScript 4.1.5。为我的项目使用响应式表单控件。

我有一个对象“Artwork”,它的属性 imageUrls 是一个字符串数组,作为它的 imageUrls。 JSON 表示形式如下所示:

{
  "title": "Mona Lisa",
  "description": "Portrait painting with a mysterious smile",
  ...
  "imageUrls": [
    "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/1280px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg"
  ],
  ...
}

在这幅作品的“编辑”视图中,我想在表单旁边渲染图像。我希望图像部分在编辑图像的 URL 时自动更新。如何在不提交整个表单的情况下实现这种“自动更新图片”?

我当前的模板如下所示:

<div fxFlex fxLayout fxLayoutAlign="start start">
  <!-- image container -->
  <div fxFlex="40" fxLayout="column" fxLayoutGap="10px">
    <div *ngIf="artworkForm.get('imageUrls')">
      <ng-container *ngFor="let imageUrl of getImageUrlCtrls(); index as i">
      <img [src]="imageUrl.value" alt="Picture {{i + 1}} of {{artworkForm.get('title')?.value}}"
           class="detailImage">
      </ng-container>
    </div>
  </div>

  <!-- form container -->
  <div fxFlex="60" fxLayout="column" fxLayoutAlign="center center">

    <!-- ~~~~~~~~~~~~~~~~~ form of the details ~~~~~~~~~~~~~~~~~~ -->
    <div class="detailForm">
      <form fxFlex fxLayout="column" fxLayoutAlign="center start"
        [formGroup]="artworkForm" (ngSubmit)="onSubmit()">
        ....
        <div class="row">
          <p>Image URLs:</p>
          <!-- without the type='button', the form will automatically submit when this button is clicked! -->
          <button type="button" *ngIf="editable()" mat-icon-button (click)="onAddImageUrl()">
            <mat-icon color="primary">add</mat-icon>
          </button>
        </div>

        <ng-container *ngIf="artworkForm.get('imageUrls')">
          <div class="row" fxLayoutAlign="flex-end"
               *ngFor="let imageUrl of getImageUrlCtrls(); index as i">
          <mat-form-field>
            <mat-label>image {{i + 1}} URL</mat-label>
            <input matInput [value]="imageUrl.value">
          </mat-form-field>

          <button type="button" *ngIf="editable()"
                  mat-icon-button
                  (click)="onDeleteImageUrl(i)">
            <mat-icon color="warn">delete_outline</mat-icon>
          </button>
          </div>
        </ng-container>
       ....
      </form>
    </div>
  </div>

我的组件如下所示:

export class ArtworkDetailComponent implements OnInit {
  
  artworkForm!: FormGroup;
  
  artwork: {[index: string]: any} = {} as Artwork;

  ....

  ngOnInit(): void {
    if (this.artworkId) {
      this.artwork = this.artworkService.getArtworkById(this.artworkId);
    }

    this.initForm();
  }

  private initForm(): void {
    ....
    const ffImageUrls = new FormArray([]);

    this.artwork.imageUrls.forEach((imageUrl: string, index: number) => {
          ffImageUrls.push(new FormControl({value: imageUrl, disabled: this.readOnly()}));
        });
    ....

    this.artworkForm = new FormGroup({
      ....
      imageUrls: ffImageUrls,
      ....
    });
  }
  
  getImageUrlCtrls(): FormControl[] {
    return (this.artworkForm.get('imageUrls') as FormArray).controls as FormControl[];
  }
}

目前,当我更改表单中的 url 时,同一页面上的图像 div 没有得到更新。任何帮助将不胜感激!

【问题讨论】:

    标签: angular data-binding angular-reactive-forms


    【解决方案1】:

    我阅读了 Netanel Basal 的博客 Angular Reactive Forms: The Ultimate Guide to FormArray 并解决了我的问题。

    我的错误在html模板中,在这一行:

    <input matInput [value]="imageUrl.value">
    

    当我把它改成:

    <input matInput [formContrl]="imageUrl">
    

    当我更改表单中的 URL 时,图像立即重新呈现。耶!!!

    为了让事情更清楚,我将变量名 imageUrl 更改为 urlCtrl。

    Netanel 的代码将无法在最新的 Angular 和最新的 TypeScript 版本中运行。由于 html 模板中缺少类型转换,编译器会报错。所以组件TS代码中的这个方法很关键:

    getImageUrlCtrls(): FormControl[] {
        return (this.artworkForm.get('imageUrls') as FormArray).controls as FormControl[];
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-30
      • 2023-03-07
      • 2023-03-14
      • 2020-09-27
      • 2018-07-15
      • 2021-05-14
      • 2018-12-22
      • 1970-01-01
      相关资源
      最近更新 更多