web-dev-qa-db-fra.com

Utilisation de * ngFor pour créer une série de boutons radio pour angular2 en utilisant le framework materialize-css

Les saisons saluent tout le monde!

J'ai le code suivant qui construit un seul bouton radio basé sur le framework materialize-css http://materializecss.com/forms.html#radio

<input name = 'group1'
       type = 'radio'
       id = 'test2'/>
<label for = 'test2'>Yellow</label>

Ma tentative d'utilisation de * ngFor est illustrée ci-dessous:

  statuses: string[] = [
    'Single',
    'Married',
    'Divorced',
    'Common-law',
    'Visiting'
  ];

  <p>{{maritalStatus?.status}}</p>
  <div *ngFor = 'let status of statuses;  let indx = index'>
    <input #widget
           class = 'with-gap'
           name = 'statusGroup'
           type = 'radio'
           id = 'status'
           [value] = 'status'
           [(ngModel)] = 'maritalStatus.status'
           (change) = 'radioBtnChange$.next(status)'
    />
    <label for = 'status'>{{status}}</label>
    <p>{{status}}{{ indx}}</p>
  </div>

Tous les boutons sont créés mais seul le premier bouton (Unique) peut être sélectionné.

Comment puis-je faire fonctionner la série de boutons comme les boutons radio devraient le faire?

Merci

9
st_clair_clarke

Plunker

Pourquoi ça ne marche pas

La variable status dans votre boucle *ngFor N'est pas utilisée dans l'attribut for de votre label ou _ id attribut de votre input.

Il existe deux options pour résoudre ce problème:

expressions de modèle

Vous pouvez utiliser une expression de modèle en mettant les attributs entre crochets comme ceci:

<input [id]="status">

c'est ce que vous avez fait (correctement) avec l'attribut value.

Une expression de modèle produit une valeur. Angular exécute l'expression et l'affecte à une propriété d'une cible de liaison; la cible peut être un élément HTML, un composant ou une directive.

interpolation

Vous pouvez utiliser l'interpolation en utilisant des accolades à double bouclé comme ceci:

<input id="{{status}}">

Plus généralement, le matériau entre les accolades est une expression de modèle qui Angular évalue d'abord puis convertit en chaîne.

Quelle est la différence?

Commander cette réponse pour une explication sur les différences entre ces méthodes.

Modèle complet HTML

<h2>Current Status</h2>
<p>{{maritalStatus?.status}}</p>

<h2>Options</h2>
<div *ngFor="let status of statuses; let indx = index">
  <input #widget
   class='with-gap'
   name='statusGroup'
   type='radio'
   [id]='status'
   [value]='status'
   [(ngModel)]='maritalStatus.status'
  />
  <label [for]='status'>{{status}}</label>
</div>

Composant complet

import {Component} from '@angular/core';
import {Http} from '@angular/http'
import {bootstrap} from '@angular/platform-browser-dynamic';

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  maritalStatus = { status: 'Nothing selected' };
  statuses: string[] = [
    'Single',
    'Married',
    'Divorced',
    'Common-law',
    'Visiting'
  ];
  constructor() { }

}

Mise à jour - Angular 2 versions <2.2.0

Si vous utilisez un Angular 2 inférieure à 2.2.0, vous devez définir explicitement l'attribut label de for comme ceci:

<label [attr.for]='status'>{{status}}</label>

car for n'est pas une propriété des éléments label.

Pourquoi?

Puisque Angular 2.2. ( 634b3bb ), Angular mappe l'attribut for à l'attribut htmlFor propriété.

Cela ressemble à beaucoup de développeurs intuitivement attendu cela , alors ils l'ont ajouté.

Tout cela était assez déroutant pour moi au début, et cet article par Pascal Precht a vraiment éclairci beaucoup de questions.

11
adriancarriger