angular - Form i form. Kan det finnas arv av formkontroller?


Jag har två komponenter: ParentComponent och ChildComponent:

parent.component.ts

<form #form="ngForm" (ngSubmit)="onSubmit(form)" novalidate>
     <input type="text" name="firstControl" [(ngModel)]="firstControl" />
     <input type="text" name="secondControl" [(ngModel)]="secondControl" />
     <child-component>
</form>
{{form.value | json}}

child.component.ts

<input type="text" name="thirdControl" [(ngModel)]="thirdControl" />
<input type="text" name="fourthControl" [(ngModel)]="fourthControl" />

Nu returnerar {{form.value | json}} { "firstControl": "", "secondControl": "" } och det är tydligt. Min fråga är: Finns det ett sätt att ärva formkontroller från ett barnkomponent? Vad är det korrekta sättet att få { "firstControl": "", "secondControl": "", "thirdControl": "", "fourthControl": "" } för ParentComponent? Är det möjligt?

Svar #1

Uppdatering:

Faktiskt finns det ett enklare sätt:

import { FormsModule, ControlContainer, NgForm, NgModel } from '@angular/forms';

@Component({
  ...
  viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}

Se även

  • Angular2 nästlad mallstyrd formulär

Föregående version:

Jag skulle säga att det är möjligt. Till exempel kan du lägga till följande kod i din

child.component.ts

import { NgForm, NgModel } from '@angular/forms';

@Component({
  selector: 'child-component',
  template: `
      <input type="text" name="thirdControl" [(ngModel)]="thirdControl" />
      <input type="text" name="fourthControl" [(ngModel)]="fourthControl" />
    `
})
export class ChildComponent {
  @ViewChildren(NgModel) ngModels: QueryList<NgModel>;

  constructor(@Optional() private ngForm: NgForm) {}

  ngAfterViewInit() {
    if (this.ngForm) {
      this.ngModels.forEach(model => this.ngForm.addControl(model));
    }
  }
}

Plunker-exempel

Angular DI-system ger oss möjlighet att få en referens till den överordnade NgForm-instansen eftersom Angulars beroendeupplösningsalgoritm börjar med den aktuella noden och går upp genom elementträdet. I mitt exempel kan vi föreställa oss följande träd

              @NgModule providers
                    |
                  my-app
                    |
                   form
          /         |       \
   input[text] input[text] child-component

Så när vi kräver NgForm-token kommer Angular att söka efter den i följande ordning

child-component
     ||
     \/
    form
     ||
     \/
   my-app
     ||
     \/
  @NgModule

På formelementet NgForm placeras direktivet så att vi kan få tag på det. Vi kan också få tag på vilken token som helst som deklarerades på NgForm-direktivet inom providers-arrayen. Och denna regel gäller för vilken nod som helst.

Se även Angular 2 - Hur tillhandahåller ng-bootstrap NgbRadioGroup och NgbButtonLabel till deras NgbRadio-direktiv?

Sedan lade jag bara till barn NgModel-direktiv manuellt till NgForm så de borde fungera tillsammans.

Relaterade artiklar