web-dev-qa-db-fra.com

Angular 2 créant des formes réactives avec des composants imbriqués

Mon exigence est que je dois créer un formulaire avec des composants imbriqués . Je crée des composants pour chaque champ de formulaire signifie pour textbox il y aurabe un composant, pour le bouton radio il y aura un autre composant comme wise.
<form [formGroup]="myForm">
<textbox-component></textbox-component>
<radioButton-component></radioButton-component>
</form>

Et je souhaite utiliser des formulaires réactifs pour créer ce formulaire, car je souhaite que mon fichier Html ne soit pas touché et que mes validations de formulaire ne soient effectuées que via TypeScript. 

Mais je ne trouve aucune solution, comment pouvons-nous avoir des formes réactives imbriquées avec des composants

18
Mahesh Saibalwar

Après mes recherches et expériences, j'ai trouvé une réponse à ma question, donc répondez-y moi-même. Si cela fait gagner du temps à quelqu'un, je serai heureux.

Si vous souhaitez créer des formulaires réactifs avec des composants imbriqués, procédez comme suit.

Ici, je crée un formulaire avec deux composants imbriqués, l'un pour la zone de texte et l'autre pour le bouton radio.

Votre composant parent peut être comme ça

<form [formGroup]="myForm">
    <child-textbox-component [parentFormGroup]="myForm">
    </child-textbox-component>
    <child-radio-button-component [parentFormGroup]="myForm">
    </child-radio-button-component>
</form>

Nous transmettons l'objet FormGroup en tant qu'entrée aux composants enfants qui ont été créés dans le composant parent En tant qu'entrée des composants enfants, ils utiliseront cet objet FormGroup dans leur composant Pour concevoir un contrôle spécifique de la classe.

Vos composants enfants seront comme ça

composant-text-enfant

<div class="form-group" [formGroup]="parentFormGroup">
  <label>
    {{control.caption}}
  </label>
  <input class="form-control" type="text" [title]="control.toolTip" 
    [attr.maxlength]="control.width" [name]="control.name"
    [value]="control.defaultValue" [formControlName]="control.name"/>
</div>

composant-bouton-radio-enfant

<div class="form-group" [formGroup]="parentFormGroup">
  <label>
    {{control.caption}}
  </label>
  <div>
      <label *ngFor="let value of control.values; let idx = index"
        class="radio-inline" [title]="control.tooltip">
        <input type="radio" [name]="control.name" [formControlName]="control.name"/>
        {{ value }}
      </label>
  </div>
</div>

Ici, contrôle représente la classe de modèle contenant les données à afficher pour ces composants enfants

De cette façon, vous pouvez générer votre formulaire à l’aide de composants imbriqués, afin que vous n’ayez pas besoin de disposer de votre formulaire (peut dire un formulaire volumineux) en composant unique Vous pouvez le décomposer en autant de sous-composants que vous le souhaitezbe facile à créer et à gérer, également à l’aide de formes réactives de Angular 2. Vous pouvez également ajouter facilement des validations.

J'ai suivi ces liens avant de répondre à cette question 

  1. quelque chose de similaire sur stackoverflow

  2. 2 formes dynamiques angulaires

36
Mahesh Saibalwar

Pour élargir la liste des réponses possibles, cet article de Alexey Zuev suggère d'utiliser provide:ControlContainer et useExisting:NgForm dans le décorateur de composants pour passer la directive ngForm à un composant enfant.

@Component({
  selector: 'registrant',
  templateUrl: 'app/register/registrant.component.html',
  **viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]**
})
1
PoorInRichfield

Note complémentaire à la réponse de Mhesh, vous pouvez créer cette même solution sans injecter [parentFormGroup] au format HTML. Vous pouvez le faire en suivant cette publication Stack Overflow sur des groupes de formulaires réutilisables.

C'est vraiment gentil. 

Exemple

Pour prendre la solution existante, vous pouvez faire la même chose, sauf que:

Votre composant parent peut être comme ça, sans aucun paramètre supplémentaire passé dans

<form [formGroup]="myForm">
    <child-textbox-component></child-textbox-component>
    <child-radio-button-component></child-radio-button-component>
</form>

Notez également que vous pouvez définir des groupes de formulaire comme ceci:

<form [formGroup]="myForm">
    <child-textbox-component></child-textbox-component>
    <child-radio-button-component formGroupName="myGroup"></child-radio-button-component>
</form>

composant-text-enfant

<div class="form-group" [formGroup]="controlContainer.control">
  <label>
    {{control.caption}}
  </label>
  <input class="form-control" type="text" [title]="control.toolTip" 
    [attr.maxlength]="control.width" [name]="control.name"
    [value]="control.defaultValue" [formControlName]="control.name"/>
</div>

Pour l'activer, vous voulez injecter une ControlContainer dans votre @Component

@Component({
    moduleId: `MODULE_ID_HERE`,
    selector: "child-textbox-component",
    templateUrl: "childTextbox.component.html",
})
export class ChildTextboxComponent {
    constructor(private controlContainer: ControlContainer, OTHER_PARAMETERS) {
    }
}
1
Stormswept

il suffit de passer le même formulaire ou le même formulaire formGroup dans le bloc de formulaire avec la liaison [formGroup]. 

0
xsilen T