【问题标题】:Nested Array in Angular Reactive Form角度反应形式的嵌套数组
【发布时间】:2020-09-02 18:59:08
【问题描述】:

我有一个任务是使用 angular 创建和编辑卷。我正在使用反应形式,但当我尝试编辑卷作者时,我无法获取它们。我在创建卷时动态生成它们,但在“编辑”中看不到它们。我尝试了很多方法,我在浏览器控制台上看到了各种错误。 这是代码:

  public createMyVolumeForm: FormGroup;

  constructor(private fb: FormBuilder,
              private router: Router,
              private volumeService: VolumeService,
              private route: ActivatedRoute) {
    this.createMyVolumeForm = this.fb.group({
      id: ['', [Validators.required]],
      volumeInfo: this.fb.group({
        title: ['', [Validators.required]],
        authors: this.fb.array([
          this.fb.control('')
        ]),
        publisher: ['', [Validators.required]],
        publishedDate: ['', [Validators.required]],
        pageCount: ['', [Validators.required]],
        imageLinks: this.fb.group({
          thumbnail: ['', [Validators.required]]
        })
      })
    });
  }

  createMyVolume(): void {
    this.volumeService.createMyVolume(this.createMyVolumeForm.value)
      .subscribe(data => {
        this.router.navigateByUrl('my-volumes');
        console.log(this.createMyVolumeForm.value);
      });
  }

  ngOnInit(): void {
    this.route.paramMap.subscribe(params => {
      const volumeId = params.get('id');
      if (volumeId) {
        this.getCurrentVolume(volumeId);
      }
    });
  }

  private getCurrentVolume(id: string): void {
    this.volumeService.getVolume(id).pipe(take(1)).subscribe(
      (volume: IVolume) => this.editVolume(volume)
    );
  }

  private editVolume(volume: IVolume): void {
    this.createMyVolumeForm.patchValue({
      id: volume.id,
      volumeInfo: {
        title: volume.volumeInfo.title,
        publisher: volume.volumeInfo.publisher,
        authors: this.fb.group(this.authors),
        publishedDate: volume.volumeInfo.publishedDate,
        pageCount: volume.volumeInfo.pageCount,
        imageLinks: {
          thumbnail: volume.volumeInfo.imageLinks.thumbnail,
        }
      }
    });
  }

  get authors(): FormArray {
    return this.createMyVolumeForm.get('volumeInfo.authors') as FormArray;
  }

  addMoreAuthors() {
    this.authors.push(this.fb.control(''));
  }
}```

HTML: 
<section class="form-holder">
  <h2 class="form-heading">Create Volume</h2>
  <form [formGroup]='createMyVolumeForm'>
    <div class="input">
      <label class="required-input" for="id">Id</label> <input id="id" type="text" formControlName="id" name="id"/>
    </div>
    <div formGroupName="volumeInfo">
      <div class="input-holder">
        <label class="required-input" for="title">Title</label>
        <div class="input">
          <input id="title" type="text" formControlName="title" name="title"/>
        </div>
        <button type="submit" class="button" (click)="addMoreAuthors()">Add Authors</button>
        <div formArrayName="authors">
          <div *ngFor="let author of authors.controls; let i = index;">
            <label>Authors</label> <input type="text" [formControlName]="i">
          </div>
        </div>
        <label class="required-input" for="publisher">Publisher</label>
        <div class="input">
          <input id="publisher" type="text" formControlName="publisher" name="publisher">
        </div>
        <label class="required-input" for="publishedDate">Published Date</label>
        <div class="input">
          <input id="publishedDate" type="text" formControlName="publishedDate" name="publishedDate">
        </div>
        <label class="required-input" for="pageCount">Page Count</label>
        <div class="input">
          <input id="pageCount" type="number" formControlName="pageCount" name="pageCount">
        </div>
        <div formGroupName="imageLinks">
          <label class="required-input" for="thumbnail">Thumbnail</label>
          <div class="input">
            <input id="thumbnail" type="text" formControlName="thumbnail" name="thumbnail">
          </div>
        </div>
      </div>
      <div class="login-button-holder">
        <input class="login-button"
               type="submit"
               [disabled]="createMyVolumeForm.invalid"
               (click)="createMyVolume()" value="Create"/>
      </div>
    </div>
  </form>
</section>

【问题讨论】:

    标签: javascript html angular typescript angular-reactive-forms


    【解决方案1】:

    FormArrays 有一个令人困惑的 API。它们不是表示数组值的 FormControl,而是表示 FormControl 的数组。因此,如果您想为表单分配一组作者,每个作者都是可编辑的,那么您需要为每个作者创建一个新控件,并将其添加到 FormArray。

    以此为例:

    private editVolume(volume: IVolume): void {
        this.createMyVolumeForm.patchValue({
          id: volume.id,
          volumeInfo: {
            title: volume.volumeInfo.title,
            publisher: volume.volumeInfo.publisher,
            authors: this.fb.group(this.authors),
            publishedDate: volume.volumeInfo.publishedDate,
            pageCount: volume.volumeInfo.pageCount,
            imageLinks: {
              thumbnail: volume.volumeInfo.imageLinks.thumbnail,
            }
          }
        });
      }
    

    一种方法是,在您分配给作者的地方,改为使用authors: new FormArray([])

    然后将值修补到表单后,执行以下操作:

    (this.createMyVolumeForm.get('authors') as FormArray).clear();
    this.authors.forEach(a => {
         const control = new FormControl(a);
         (this.createMyVolumeForm.get('authors') as FormArray).add(control);
    });
    

    希望这能让你走上正轨。

    【讨论】:

      【解决方案2】:

      谢谢杰西, 你的回答真的让我在一周内走上了正轨:

       showExistingAuthors(volume: IVolume): void {
          (this.createMyVolumeForm.get('volumeInfo.authors') as FormArray).clear();
          volume.volumeInfo.authors.forEach(a => {
            const control = new FormControl(a);
            (this.createMyVolumeForm.get('volumeInfo.authors') as FormArray).push(control);
          });
        }```
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-04
        • 1970-01-01
        • 2017-08-04
        • 2018-07-31
        • 1970-01-01
        • 1970-01-01
        • 2019-05-29
        • 1970-01-01
        相关资源
        最近更新 更多