web-dev-qa-db-fra.com

Formulaire réactif pour chaque ligne du tableau

J'utilise Angular 2 et je veux valider les contrôles dans chaque ligne séparément. Mais je n'ai aucun moyen de le faire. Je veux que cela se fasse en utilisant des formulaires réactifs uniquement et non en utilisant une approche basée sur un modèle. Je veux [formGroup] sur chaque <tr>. Toute aide serait appréciée. Voici la structure de mon code:

<tbody *ngFor="let single of allTeamDetails"                
       [ngClass]="{'alternate-row-color': $even}">
  <tr>
    <td class="td-data first-column">
      <input type="text" class="input-text form-control" 
             [value]="single.first_name">
    </td>
    <td class="td-data second-column">
      <input type="text" class="input-text form-control" 
             [value]="single.last_name">
    </td>
    <td class="td-data third-column">
      <input type="email" class="input-text form-control" 
             [value]="single.email">
    </td>
    <td class="td-data fourth-column">
      <select class="selection-dropdown width-80-percent" 
              [value]="single.user_role">
        <option *ngFor="let singleRole of allUserRole"      
                value="{{singleRole.name}}"> 
                {{setUserRoleAndType(singleRole.name)}}</option>
      </select>
    </td>
    <td class="td-data fifth-column" >
      <input type="password" class="input-text form-control">
    </td>
    <td class="td-data sixth-column" >
      <input type="password" class="input-text form-control">
    </td>
    <td class="td-data save-send-tm-data">
      <button class="btn save-user-details save-sub-account-details"                                                      
              type="button" data-toggle="tooltip" title="Save">
        <i class="fa fa-floppy-o" aria-hidden="true"></i>
      </button>
    </td>
    <td class="td-data save-send-tm-data">
      <button type="button"                                      
              class="btn save-user-details save-sub-account-details"  
              data-toggle="tooltip" title="Send Message"                       
              (click)="openSendMessageModal(single.email)">
        <i class="fa fa-envelope" aria-hidden="true"></i> 
      </button>
    </td>
  <tr>
</tbody>
8
GeniusGo

Utilisez formArray. Vous allez créer un formGroup (formulaire maître) contenant plusieurs formGroup multiples et plus petits. Chaque plus petit groupe sera ce qui sera répété dans votre *ngFor.

Votre formulaire devrait ressembler à ceci:

<!--This is your master form-->
<form [formGroup]="teamForm">
  <!--Use formArray to create multiple, smaller forms'-->
  <div formArrayName="memberDetails">
    <div *ngFor="let single of allTeamDetails; let $index=index">
      <div [formGroupName]="$index">
        <div>
          <!--your field properties of every repeated items-->
          <input placeholder="First Name" type="text" formControlName="firstName" />
        </div>
        <div>
          <input placeholder="Last Name" type="text" formControlName="lastName" />
        </div>
      </div>
    </div>
  </div>
</form>

Dans votre composant, vous pouvez utiliser le formBuilder angulaire pour aider à construire un formulaire.

Dans votre constructeur:

  constructor(private formBuilder: FormBuilder) {
    this.teamForm = this.formBuilder.group({
      memberDetails: this.formBuilder.array([])
    });
  }

Vous pouvez maintenant initialiser toutes les propriétés de vos modèles répétés. Vous pouvez ensuite personnaliser chaque validateur de chaque champ. Notez les propriétés de votre fichier TypeScript qui correspondent à celles en html. Je fais tout cela dans ngOnInit pour que les propriétés puissent être liées au html avant d'être rendues.

  ngOnInit() {   
    this.teamForm = this.formBuilder.group({
      memberDetails: this.formBuilder.array(
        this.allTeamDetails.map(x => this.formBuilder.group({
          firstName: [x.first_name, [Validators.required, Validators.minLength(2)]],
          lastName: [x.last_name, [Validators.required, Validators.minLength(2)]]
        }))
      )
    })
  }

Après tout cela, l'ajout de messages de validation est très trivial. Les avantages de le faire de cette façon?

  1. étant donné que chaque instance est désormais un formGroup unique, vous pouvez personnaliser votre logique de validation jusqu'à un niveau très granulaire.

  2. Comme indiqué ci-dessus, vous pouvez vous abonner à chaque valueChange de chaque petit formulaire, jusqu'à chaque champ unique. Par exemple, si vous souhaitez vous abonner au changement de champ du prénom du premier membre de l'équipe, vous pouvez le faire:

      this.teamForm
       .controls.memberDetails
       .controls[0] //get the first instance!
       .controls.firstName  //get the firstName formControlName
       .valueChange 
       .subscribe(x=>console.log('value changed!))
    
  3. Si vous souhaitez valider le formulaire maître, vous pouvez également le faire.

Ont créé un plnkr , juste pour vous :)

19
CozyAzure