Angular Реактивные формы, FormArray очищается после отправки формы - PullRequest
0 голосов
/ 10 марта 2020

Я только начал с 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()
});

Проект-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>

Мой проект-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 профи мог бы помочь мне.

1 Ответ

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

Единственное, что я вижу, что он настроен неправильно, это то, что вы передаете значения массива для фазных дат.

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

Обратите внимание, как в этой демонстрации структура даты фазы меняются, когда вы 1. отправляете форму, 2. изменяете дату фазы, 3. отправляете форму снова

Вместо этого вы должны передать скалярное значение:

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

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

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

...