web-dev-qa-db-fra.com

matrices de liaison bidirectionnelles en angle 2

Je suis conscient de la liaison de base à 2 voies en angle 2, comme indiqué dans la documentation.

J'ai un tableau de persons, que j'utilise pour construire une liste HTML:

Maintenant, lorsque je clique sur la ligne d'une personne, je peux la modifier à l'aide d'une liaison bidirectionnelle: 

 <form>
    <label>Name: </label>
    <input [(ngModel)]="selectedPerson.name" name="name"/>

    <label>Description: </label>
    <input [(ngModel)]="selectedPerson.job" name="job"/>
</form>

Maintenant, ce que je veux, c'est relier la liste elle-même dans les deux sens: (La liste est dans une vue différente de celle de l'éditeur de lignes)

 <div class='row' *ngFor="let person of model">
    <div class='col'>{{person.name}}</div>
    <div class='col'>{{person.job}}</div>
 </div>

Actuellement, j'utilise *ngFor pour lister toutes les personnes. Si ma model est un tableau de deux personnes, je reçois deux lignes. Il y a des cas où la model peut changer pour avoir 3 ou 4 personnes. Existe-t-il un moyen de détecter cela par un angle et d’ajouter des rangées en conséquence? [(ngModel)] ne semble pas être applicable ici.

En gros, je veux que ma vue en liste se mette à jour sans avoir à actualiser la page. Comment faire en sorte que la model utilisée dans ngFor soit à l'écoute des modifications?

6
Snowman

Voici un exemple de la façon dont vous pouvez lier votre variable model à un autre composant:

https://plnkr.co/edit/tM20HcUIx13ZUPh0faTB?p=preview

J'ai créé un composant liste simple à partir de votre code ci-dessus:

import { Component, Input  } from '@angular/core';

import { Person } from './person';

@Component({
  selector: 'my-list',
  template:`
    <h3>The List</h3>
    <tr class='row' *ngFor="let person of model">
      <td class='col'>{{person.name}}</td>
      <td class='col'>{{person.job}}</td>
    </tr>
})

export class List {
  @Input() model:Array<Person>;  
}

Le décorateur Input permet au composant de savoir s’attendre à une entrée de ce type et de l’utiliser dans le cadre de ce composant.

Dans le modèle du composant éditeur, j'ai utilisé la directive my-list et défini l'entrée de modèle de la directive sur le modèle du composant éditeur.

<my-list [model]="model" ></my-list>

Cela permet maintenant de refléter toutes les modifications apportées au modèle dans le composant de la liste des enfants.

Si vous souhaitez notifier un composant qui n'est pas un enfant du composant éditeur, vous devez utiliser le décorateur @Output et configurer une variable EventEmitter à laquelle un écouteur peut être lié puis utilisé pour mettre à jour la liste ailleurs.

Jetez un coup d'œil à la documentation ici:

https://angular.io/docs/ts/latest/cookbook/component-communication.html

3
David Blaney

Merci à @ David Blaney. Je ne suis pas sûr de pouvoir le poster. Je voulais seulement étendre votre exemple pour modifier la grille/le tableau avec un tableau de liaison bidirectionnel directement sur chaque ligne de la table-angular se charge de mettre à jour le tableau alors que l'utilisateur écrit dans "l'élément d'entrée directement dans la table". L'utilisateur peut rapidement éditer les éléments sans d'abord sélectionner la ligne dans la table. Dans l'exemple original de @David Blaney dans le lecteur de répertoire, je viens de remplacer l'élément table dans app/editor.component.ts par ceci:

<form id="bigForm">
  <table>
    <tr class='row'>
        <th class='col'>Name</th>
        <th class='col'>Job</th>
    </tr>
    <tr class='row' *ngFor="let person of model; let i = index" (click)="selectPerson(person)" >
      <td class='col'>
        <input [id]="'person.name' + i" [(ngModel)]="person.name" [name]="'person.name' + i"/>
        - {{person.name}}
      </td>
      <td class='col'>{{person.job}}</td>
    </tr>
  </table>
</form>

Ensuite, je peux publier plusieurs lignes modifiées sur le serveur http en une seule requête.

2
vlakov

Vous ne voulez rien faire à regarder sur le changement de tableau. Angular prend soin de vous.

Voici l'exemple de travail pour votre problème. ngPar exemple

1
Thaadikkaaran