Angular Reactive Forms,提交表单后清除FormArray

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

我刚开始使用Angular。我有一个项目列表,在编辑其中一个项目并提交表单后,FormArray信息未显示在我的项目详细信息中。如果我再次编辑项目,那么表单中的所有项目信息都将消失(所有输入字段均为空)。这是控制台错误:

ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

   Example:


<div [formGroup]="myGroup">
  <input formControlName="firstName">
</div>

In your class:

this.myGroup = new FormGroup({
   firstName: new FormControl()
});

The project-edit.component.html:

  <form [formGroup]="projectForm" (ngSubmit)="onSubmit()">
  <div class="main">
    <div class="nameandleader form-group">
      <div class="row">
        <div class="col-md-12">
        </div>
        <div class="col-md-6">
          <label for="name">Projektname</label>
          <input type="text"
                 id="name"
                 formControlName="name"
                 class="form-control"
                 required>
        </div>
        <div class="col-md-6">
          <label for="leader">Projektleiter</label>
          <input type="text"
                 id="leader"
                 formControlName="leader"
                 class="form-control"
                 required>
        </div>
      </div>
    </div>
    <hr />
    <div class="form-group">
      <div class="row">
        <div class="col-md-6">
          <label for="start">Projektstart</label>
          <input type="date"
                 id="start"
                 formControlName="start"
                 class="form-control"
                 required>
        </div>
        <div class="col-md-6">
          <label for="name">Projektende</label>
          <input type="date"
                 id="end"
                 formControlName="end"
                 class="form-control"
                 required>
        </div>
      </div>
    </div>
    <hr />
    <div class="row">
      <div class="col-md-12">
        <h3>Phasen</h3>
      </div>
    </div>
    <div class="phase">
      <div class="row">
        <div class="col-md-12" formArrayName="phases">
          <div class="row" *ngFor="let phaseCtrl of controls; let i = index" [formGroupName]="i" style="margin-top:10px;">
            <div class="col-md-3">
              <input type="text" class="form-control" formControlName="pName" placeholder="Phasenname"/>
            </div>
            <div class="col-md-4">
              <input type="date" class="form-control" formControlName="pStart"/>
            </div>
            <div class="col-md-4">
              <input type="date" class="form-control" formControlName="pEnd"/>
            </div>
            <div class="col-md-1">
              <button class="btn btn-danger" (click)="onDeletePhase(i)">X</button>
            </div>
          </div>
          <div class="row">
            <div class="col-md-12">
              <hr />
              <button type="button" class="btn btn-success" (click)="onAddPhase()">Phase hinzufügen</button>

            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-12 buttons">
        <button class="btn btn-success" type="submit" [disabled]="!projectForm.valid">Projekt speichern</button>
        <button class="btn btn-danger" type="button" (click)="onCancel()">Verwerfen</button>
      </div>
    </div>
  </div>
</form>

我的project-edit.component.ts:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
import { ProjectService } from '../../shared/project.service';
import { formatDate } from '@angular/common';


@Component({
  selector: 'app-project-edit',
  templateUrl: './project-edit.component.html',
  styleUrls: ['./project-edit.component.css']
})
export class ProjectEditComponent implements OnInit {
  projectForm: FormGroup;
  id: number;
  editMode = false;
  projectPhases = [];


  constructor(private route: ActivatedRoute, private projectService: ProjectService, private router: Router) {
  }

  ngOnInit() {
    this.route.params.subscribe(
      (params: Params) => {
        this.id = +params['id'];
        this.editMode = params['id'] != null;
        this.initForm();
      }
    );
  }
  onSubmit() {

    if (this.editMode) {
      this.projectService.updateProject(this.id, this.projectForm.value);
    } else {
      this.projectService.addProject(this.projectForm.value);
    }
    this.onCancel();
  }

  get controls() {
    return (<FormArray>this.projectForm.get('phases')).controls;
  }



  onAddPhase() {
    (<FormArray>this.projectForm.get('phases')).push(
      new FormGroup({
        'pName': new FormControl(null, [Validators.required]),
        'pStart': new FormControl(null, [Validators.required]),
        'pEnd': new FormControl(null, [Validators.required])
      })
    );
  }
  onDeletePhase(index: number) {
    (<FormArray>this.projectForm.get('phases')).removeAt(index);
  }

  onCancel() {
    this.router.navigate(['../'], { relativeTo: this.route });
  }

  private initForm() {

    let projectName = '';
    let projectLeader = '';
    let projectStart = new Date();
    let projectEnd = new Date();
    let projectPhases = new FormArray([]);



    if (this.editMode) {
      const project = this.projectService.getProject(this.id);
      projectName = project.name;
      projectLeader = project.leader;
      projectStart = project.start;
      projectEnd = project.end;

      if (project['phases']) {
        for (let phase of project.phases) {
          projectPhases.push(
            new FormGroup({
              'pName': new FormControl(phase.name, Validators.required),
              'pStart': new FormControl([formatDate(phase.start, 'yyyy-MM-dd', 'en')], [Validators.required]),
              'pEnd': new FormControl([formatDate(phase.end, 'yyyy-MM-dd', 'en')], [Validators.required])
            })
          );
        }
      }
    }


    this.projectForm = new FormGroup({
      'name': new FormControl(projectName, Validators.required),
      'leader': new FormControl(projectLeader, Validators.required),
      'start': new FormControl([formatDate(projectStart, 'yyyy-MM-dd', 'en')], [Validators.required]),
      'end': new FormControl([formatDate(projectEnd, 'yyyy-MM-dd', 'en')], [Validators.required]),
      'phases': projectPhases
    });
  }
}

如果有经验的专业人士可以帮助我,那将很棒。

angular forms input reactive formarray
1个回答
0
投票

我唯一看到的设置错误是,您正在为阶段日期传递数组值。

'pStart': new FormControl(
  [formatDate(phase.start, 'yyyy-MM-dd', 'en')], 
  [Validators.required]
)

您应该传递标量值:

'pStart': new FormControl(
  formatDate(phase.start, 'yyyy-MM-dd', 'en'), 
  [Validators.required]
)

除此之外,这是创建复杂表格的非常可靠的尝试。您正在使用的所有技术都是用于创建相对形式的教科书方式。

DEMO:https://stackblitz.com/edit/angular-jcuc1n

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