javascript - Angular reaktive nestede skjemaer


Jeg prøver å nestle flere reaktive skjemaer i Angular-prosjektet mitt, og skjemaene er i forskjellige komponenter.

For eksempel har jeg en komponent som inneholder et skjema med to inndatafelt, ett inndatafelt for navn og ett inndatafelt for beskrivelse, og en send-knapp. Jeg kaller denne komponenten NameDescComponent

Jeg planlegger å bruke denne komponenten på flere sider og skjemaer. Her er HTML-en for komponenten.

<form [formGroup]="nameDescForm" (ngSubmit)="customEmit()">
    <div fxLayout="row" fxLayoutGap="10px" fxFlex>
      <mat-form-field>
        <input matInput placeholder="Name" formControlName="name">
      </mat-form-field>
      <mat-form-field fxFlex>
        <input matInput placeholder="Description" formControlName="description">
      </mat-form-field>
    </div>
    <div fxLayout="column" fxLayoutGap="10px">
      <button type="submit" mat-raised-button color="primary">
        {{buttonText}}
      </button>
      <div>
      </div>
    </div>
  </form>

Og her er den forkortede ts-filen

public nameDescForm: FormGroup;



@Input() public buttonText: string;
  @Output() public save: EventEmitter<any> = new EventEmitter<any>();
  @Output() public nameDescFormEmit: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();

  constructor(fb: FormBuilder) {
    this.nameDescForm = fb.group({
      'name': ['', Validators.required],
      'description': ['']
    });
  }

  public ngOnInit() {
    console.log(this.nameDescForm);
    this.nameDescFormEmit.emit(this.nameDescForm);
  }

  public customEmit() {
    this.save.emit();
  }

Så på en side hvor jeg bruker denne komponenten, har jeg også et annet skjema med NameDescComponent inne i skjemaet, slik som dette

<form [formGroup]="parentForm" (ngSubmit)="customEmit()">

  <app-name-description (nameDescFormEmit)="getNameDescForm($event)" buttonText="Save" (save)="save()"></app-name-description>

  <input type="test" formControlName="test">

</form>

For øyeblikket sender jeg nameDescFrom fra komponenten sin til ParentComponent med Output og EventEmitter. Denne løsningen ser ut til å fungere, og når jeg oppdaterer child kan jeg få tilgang til verdiene. Men ulempen er at når jeg skal sende inn skjemaet, må jeg sjekke at både parentForm og nameDescFrom er gyldige og håndtere begge skjemaene separat.

Jeg lurer på om det finnes en bedre måte å tilnærme seg dette på? Når kan jeg få tilgang til nameDescFrom fra innenfor foreldreskjemaet?

Takk

Svar #1

For å slå sammen skjemaet ditt med nestede skjemaer og ha en enkelt valideringsprosess for alle, kan du bruke formbuilder til å lage hele modellobjektstrukturen i rotskjemakomponenten. Deretter i HTML-malen legger du til det tilpassede elementet for under-skjemaene (f.eks.: <nested-form>), som vil gjengi under-skjemaene.

Se eksempel: https://stackblitz.com/edit/angular-m5fexe)

Nyttige lenker til Angular-dokumentasjon:

  • https://angular.io/guide/reactive-forms#creating-nested-form-groups
  • https://angular.io/guide/reactive-forms#step-3-generating-form-controls

Kode :

export class Form1Component  {
  @Input() name: string;

  public dummyForm: FormGroup;

  constructor(
      private _fb: FormBuilder,
  ) {
      this.createForm();
  }

  createForm() {
    this.dummyForm = this._fb.group({
      username: ['username', Validators.required],
      nestedForm: this._fb.group({        
        complement1: ['complement1', Validators.required],
        complement2: ['complement2', Validators.required],
      })
    });
  }

  submit() {
    if (this.dummyForm.valid) {
      console.log('form AND subforms are valid', this.dummyForm.value);
    } else {
      console.warn('form AND/OR subforms are invalid', this.dummyForm.value);
    }
  }
}

Mal for Form1Component:

<form [formGroup]="dummyForm" (ngSubmit)="submit()">    
    <div>
      <label for="username">Root Input</label>
      <input type="text" id="username" formControlName="username"/>
    </div>
    <nested-form [parentForm]="dummyForm"></nested-form>
    <button>Send</button>    
  </form>

Nestet skjema-kode:

export class NestedFormComponent {
  @Input()
  public parentForm: FormGroup;
}

Nestet skjema mal :

<form [formGroup]="parentForm">
    <div formGroupName="nestedForm">
      <div>
        <label for="complement1">Nested input 1</label>
        <input type="text" formControlName="complement1"/>
      </div>
      <div>
        <label for="complement1">Nested input 1</label>
        <input type="text" formControlName="complement2"/>
      </div>
    </div>
  </form>

Relaterte artikler