Использование * ngFor для создания серии переключателей для angular2 с использованием среды materialize-css

Сезоны всем привет!

У меня есть следующий код, который создает один переключатель на основе среды materialize-css http://materializecss.com/forms.html#radio

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

Моя попытка использования *ngFor показана ниже:

  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>

Создаются все кнопки, но выбрать можно только первую кнопку (одиночную).

Как я могу заставить серию кнопок работать так, как ожидается от радио-кнопок?

Спасибо


person st_clair_clarke    schedule 25.12.2016    source источник


Ответы (1)


Планкер

Почему это не работает

Переменная status в вашем цикле *ngFor не используется в атрибуте for вашего label или в атрибуте id вашего input.

Есть два варианта исправить это:

Выражения шаблона

Вы можете использовать выражение шаблона, поместив атрибуты в квадратные скобки следующим образом:

<input [id]="status">

что вы и сделали (правильно) с атрибутом value.

Выражение шаблона создает значение. Angular выполняет выражение и присваивает его свойству цели привязки; целью может быть элемент HTML, компонент или директива.

Интерполяция

Вы можете использовать интерполяцию, используя двойные фигурные скобки следующим образом:

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

В более общем смысле материал между фигурными скобками — это шаблонное выражение, которое Angular сначала оценивает, а затем преобразует в строку.

Какая разница?

Ознакомьтесь с этот ответ для объяснения различий между этими методами.

Полный 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>

Полный компонент

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() { }

}

Обновление — версии Angular 2 ‹ 2.2.0

Если вы используете версию Angular 2 ниже 2.2.0, вам необходимо явно установить атрибут for label следующим образом:

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

потому что for не является свойством label элементов.

Почему?

Начиная с Angular 2.2.0 (634b3bb), Angular сопоставляет атрибут for со связанным свойством htmlFor.

Похоже, что многие разработчики интуитивно ожидали этого, поэтому добавили его.

Поначалу все это было довольно запутанным для меня, и эта статья Паскаля Прехта действительно прояснила много вопросов.

person adriancarriger    schedule 25.12.2016
comment
Отлично, и спасибо. Две небольшие настройки, которые мне пришлось сделать, чтобы заставить его работать - и id на входе, и for на метке являются атрибутами, а НЕ свойствами. Следовательно, мне пришлось добавить к обоим префикс attr, чтобы он работал. См. EDIT1 выше, чтобы узнать, что работает для меня. Спасибо - person st_clair_clarke; 25.12.2016
comment
На самом деле необходима только одна настройка — для метки, поскольку id является одновременно и свойством, и атрибутом. - person st_clair_clarke; 25.12.2016
comment
Я только что узнал, что это необходимо только в том случае, если вы используете версию Angular 2 ниже 2.2.0. Сначала я был довольно сбит с толку, и оказалось, что они недавно добавили это как функцию. Спасибо, что указали на это, так как это привело к интересному изучению фреймворка! - person adriancarriger; 26.12.2016