Angular2 - привязка кнопок радио
Я хочу использовать радиокнопку в форме с помощью Angular 2
Options : <br/>
1 : <input name="options" ng-control="options" type="radio" value="1" [(ng-model)]="model.options" ><br/>
2 : <input name="options" ng-control="options" type="radio" value="2" [(ng-model)]="model.options" ><br/>
Начальное значение
model.options равно 1
когда страница загружена, первый переключатель не отмечен, и изменения не привязаны к модели
Любая идея?
Ответы
Ответ 1
используйте [значение] = "1" вместо value = "1"
<input name="options" ng-control="options" type="radio" [value]="1" [(ngModel)]="model.options" ><br/>
<input name="options" ng-control="options" type="radio" [value]="2" [(ngModel)]="model.options" ><br/>
Edit:
Как было предложено thllbrg "Для angular 2.1+ используйте [(ngModel)]
вместо [(ng-model)]
"
Ответ 2
Примечание. Теперь привязка переключателя привязки поддерживается в RC4 - см. этот ответ
Пример кнопки "Радио" с использованием пользовательского параметра RadioControlValueAccessor, аналогичного флажку CheckboxControlValueAccessor (Обновлено с помощью Angular 2 rc-1)
App.ts
import {Component} from "@angular/core";
import {FORM_DIRECTIVES} from "@angular/common";
import {RadioControlValueAccessor} from "./radio_value_accessor";
import {bootstrap} from '@angular/platform-browser-dynamic';
@Component({
selector: "my-app",
templateUrl: "template.html",
directives: [FORM_DIRECTIVES, RadioControlValueAccessor]
})
export class App {
model;
constructor() {
this.model = {
sex: "female"
};
}
}
template.html
<div>
<form action="">
<input type="radio" [(ngModel)]="model.sex" name="sex" value="male">Male<br>
<input type="radio" [(ngModel)]="model.sex" name="sex" value="female">Female
</form>
<input type="button" value="select male" (click)="model.sex='male'">
<input type="button" value="select female" (click)="model.sex='female'">
<div>Selected Radio: {{model.sex}}</div>
</div>
radio_value_accessor.ts
import {Directive, Renderer, ElementRef, forwardRef} from '@angular/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/common';
export const RADIO_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RadioControlValueAccessor),
multi: true
};
@Directive({
selector:
'input[type=radio][ngControl],input[type=radio][ngFormControl],input[type=radio][ngModel]',
host: {'(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()'},
bindings: [RADIO_VALUE_ACCESSOR]
})
export class RadioControlValueAccessor implements ControlValueAccessor {
onChange = (_) => {};
onTouched = () => {};
constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}
writeValue(value: any): void {
this._renderer.setElementProperty(this._elementRef.nativeElement, 'checked', value == this._elementRef.nativeElement.value);
}
registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; }
registerOnTouched(fn: () => {}): void { this.onTouched = fn; }
}
Источник: https://github.com/angular2-school/angular2-radio-button
Демо-версия Plunker: http://plnkr.co/edit/aggee6An1iHfwsqGoE3q?p=preview
Ответ 3
Мое ручное обходное решение, которое включает в себя ручное обновление model.options
при выборе нового переключателя:
template: `
<label *ngFor="let item of radioItems">
<input type="radio" name="options" (click)="model.options = item"
[checked]="item === model.options">
{{item}}
</label>`
class App {
radioItems = 'one two three'.split(' ');
model = { options: 'two' };
}
Этот Plunker демонстрирует вышеизложенное, а также как использовать кнопку для изменения выбранного переключателя - то есть, чтобы доказать что привязка данных является двусторонней:
<button (click)="model.options = 'one'">set one</button>
Ответ 4
Вот лучший способ использования переключателей в Angular2. Нет необходимости использовать событие (click) или RadioControlValueAccessor для изменения значения свойства привязки, при этом свойство [checked] выполняет трюк.
<input name="options" type="radio" [(ngModel)]="model.options" [value]="1"
[checked]="model.options==1" /><br/>
<input name="options" type="radio" [(ngModel)]="model.options" [value]="2"
[checked]="model.options==2" /><br/>
Я опубликовал пример использования переключателей:
Angular 2: как создать переключатели из перечисления и добавить двустороннюю привязку?
Он работает по меньшей мере с Angular 2 RC5.
Ответ 5
Эта проблема решается в версии Angular 2.0.0-rc.4 соответственно в формах.
Включить "@angular/forms": "0.2.0"
в package.json.
Затем разверните свой загрузочный файл в главном окне. Соответствующая часть:
...
import { AppComponent } from './app/app.component';
import { disableDeprecatedForms, provideForms } from '@angular/forms';
bootstrap(AppComponent, [
disableDeprecatedForms(),
provideForms(),
appRouterProviders
]);
У меня это в .html и отлично работает:
value: {{buildTool}}
<form action="">
<input type="radio" [(ngModel)]="buildTool" name="buildTool" value="gradle">Gradle <br>
<input type="radio" [(ngModel)]="buildTool" name="buildTool" value="maven">Maven
</form>
Ответ 6
Я искал правильный метод для обработки этих радиокнопдок, вот пример решения, которое я нашел здесь:
<tr *ngFor="let entry of entries">
<td>{{ entry.description }}</td>
<td>
<input type="radio" name="radiogroup"
[value]="entry.id"
(change)="onSelectionChange(entry)">
</td>
</tr>
Обратите внимание на onSelectionChange, который передает текущий элемент методу.
Ответ 7
Радиовход пока не поддерживается.
Должен быть аксессуар для ввода радиовхода (аналогично флажку one, где он устанавливает 'checked' attr здесь), но я не нашел. Поэтому я реализовал один; вы можете проверить это здесь.
Ответ 8
[значение] = "item" с помощью * ngFor также работает с реактивными формами в Angular 2 и 4
<label *ngFor="let item of items">
<input type="radio" formControlName="options" [value]="item">
{{item}}
</label>`
Ответ 9
Следующее исправило мою проблему, рассмотрите возможность добавления радиовхода в тег form
и используйте тег [value]
для отображения значения.
<form name="form" (ngSubmit)="">
<div *ngFor="let item of options">
<input [(ngModel)]="model.option_id" type="radio" name="options" [value]="item.id"> {{ item.name }}
</div>
</form>
Ответ 10
Вот решение, которое работает для меня. Он включает привязку переключателя, но не привязку к бизнес-данным, а привязку к состоянию переключателя. Вероятно, это НЕ лучшее решение для новых проектов, но подходит для моего проекта. У моего проекта есть тонна существующего кода, написанного по другой технологии, которую я портирую на Angular. Старый код следует шаблону, в котором код очень заинтересован в проверке каждой переключательной кнопки, чтобы увидеть, является ли она выбранной. Решение представляет собой разновидность решений для обработчиков кликов, некоторые из которых уже упоминались в Qaru.
Добавленная стоимость этого решения может быть:
-
Работает с шаблоном старого кода, с которым мне приходится работать.
- Я создал вспомогательный класс, чтобы попытаться уменьшить количество операторов if в обработчике кликов и для обработки любой группы переключателей.
Это решение включает в себя
-
Использование разных моделей для каждой кнопки-переключателя.
- Установка атрибута "флажок" с помощью модели переключателя.
- Передача модели переключаемой кнопки в класс помощника.
- Вспомогательный класс обеспечивает актуальность моделей.
- Во время "отправки" это позволяет старому коду проверять состояние переключатели, чтобы узнать, какая из них выбрана, путем изучения моделей.
Пример:
<input type="radio"
[checked]="maleRadioButtonModel.selected"
(click)="radioButtonGroupList.selectButton(maleRadioButtonModel)"
...
<input type="radio"
[checked]="femaleRadioButtonModel.selected"
(click)="radioButtonGroupList.selectButton(femaleRadioButtonModel)"
...
Когда пользователь нажимает переключатель, метод selectButton вспомогательного класса
вызывается. Передается модель для радио кнопки, которая была нажата.
Вспомогательный класс устанавливает для логического поля "selected" переданной модели значение true, а для поля "selected" всех других моделей переключателей устанавливается значение false.
Во время инициализации компонент должен создать экземпляр вспомогательного класса со списком всех моделей переключателей в группе. В этом примере "radioButtonGroupList" будет экземпляром вспомогательного класса, код которого:
import {UIButtonControlModel} from "./ui-button-control.model";
export class UIRadioButtonGroupListModel {
private readonly buttonList : UIButtonControlModel[];
private readonly debugName : string;
constructor(buttonList : UIButtonControlModel[], debugName : string) {
this.buttonList = buttonList;
this.debugName = debugName;
if (this.buttonList == null) {
throw new Error("null buttonList");
}
if (this.buttonList.length < 2) {
throw new Error("buttonList has less than 2 elements")
}
}
public selectButton(buttonToSelect : UIButtonControlModel) : void {
let foundButton : boolean = false;
for(let i = 0; i < this.buttonList.length; i++) {
let oneButton : UIButtonControlModel = this.buttonList[i];
if (oneButton === buttonToSelect) {
oneButton.selected = true;
foundButton = true;
} else {
oneButton.selected = false;
}
}
if (! foundButton) {
throw new Error("button not found in buttonList");
}
}
}
Ответ 11
Простейшее решение и обходное решение:
<input name="toRent" type="radio" (click)="setToRentControl(false)">
<input name="toRent" type="radio" (click)="setToRentControl(true)">
setToRentControl(value){
this.vm.toRent.updateValue(value);
alert(value); //true/false
}
Ответ 12
Я создал версию, используя только событие click для загруженных элементов и передавая значение выбора в функцию "getSelection" и обновляя модель.
В вашем шаблоне:
<ul>
<li *ngFor="let p of price"><input type="radio" name="price" (click)="getValue(price.value)" value="{{p}}" #price> {{p}}
</li>
</ul>
Ваш класс:
export class App {
price:string;
price = ["1000", "2000", "3000"];
constructor() { }
model = new SomeData(this.price);
getValue(price){
this.model.price = price;
}
}
См. пример: https://plnkr.co/edit/2Muje8yvWZVL9OXqG0pW?p=info
Ответ 13
Хотя этот ответ может быть не лучшим в зависимости от вашего варианта использования, он работает. Вместо использования переключателя для выбора мужского и женского пола, использование <select> </select>
прекрасно работает как для сохранения, так и для редактирования.
<select formControlName="gender" name="gender" class="">
<option value="M">Male</option>
<option value="F">Female</option>
</select>
Все вышеперечисленное должно хорошо работать для редактирования с использованием FormGroup с patchValue
. Для создания вы можете использовать [(ngModel)]
вместо formControlName
. Все еще работает.
Сантехнические работы, связанные с переключателем один, я выбрал вместо этого выбрать. Визуально и с точки зрения UX, это не кажется лучшим, но с точки зрения разработчика, это намного проще.
Ответ 14
Вот код, который я использую, который работает с Angular 7
(Примечание: в прошлом я иногда использовал информацию, предоставленную ответом Энтони Бренельера, что я ценю. Но, по крайней мере для Angular 7, эта часть:
[checked]="model.options==2"
Я счел ненужным.)
Мое решение здесь имеет три преимущества:
- Соответствует наиболее часто рекомендуемым решениям. Так что это хорошо для новых проектов.
- Также позволяет коду переключателя быть похожим на код Flex/ActionScript. Это лично важно, потому что я перевожу код Flex на Angular. Как и код Flex/ActionScript, он позволяет коду работать с объектом переключателя, чтобы проверять, снимать или проверять, установлен ли переключатель.
- В отличие от большинства решений, которые вы увидите, он основан на объектах. Одним из преимуществ является организация: она группирует поля привязки данных переключателя, такие как выбранные, включенные, видимые и, возможно, другие.
Пример HTML:
<input type="radio" id="byAllRadioButton"
name="findByRadioButtonGroup"
[(ngModel)]="findByRadioButtonGroup.dataBindingValue"
[value]="byAllRadioButton.MY_DATA_BINDING_VALUE">
<input type="radio" id="byNameRadioButton"
name="findByRadioButtonGroup"
[(ngModel)]="findByRadioButtonGroup.dataBindingValue"
[value]="byNameRadioButton.MY_DATA_BINDING_VALUE">
Пример TypeScript:
findByRadioButtonGroup : UIRadioButtonGroupModel
= new UIRadioButtonGroupModel("findByRadioButtonGroup",
"byAllRadioButton_value",
(groupValue : any) => this.handleCriteriaRadioButtonChange(groupValue)
);
byAllRadioButton : UIRadioButtonControlModel
= new UIRadioButtonControlModel("byAllRadioButton",
"byAllRadioButton_value",
this.findByRadioButtonGroup) ;
byNameRadioButton : UIRadioButtonControlModel
= new UIRadioButtonControlModel("byNameRadioButton",
"byNameRadioButton_value",
this.findByRadioButtonGroup) ;
private handleCriteriaRadioButtonChange = (groupValue : any) : void => {
if ( this.byAllRadioButton.selected ) {
// Do something
} else if ( this.byNameRadioButton.selected ) {
// Do something
} else {
throw new Error("No expected radio button selected");
}
};
Используются два класса:
Группа переключателей:
export class UIRadioButtonGroupModel {
private _dataBindingValue : any;
constructor(private readonly debugName : string,
private readonly initialDataBindingValue : any = null, // Can be null or unspecified
private readonly notifyOfChangeHandler : Function = null // Can be null or unspecified
) {
this._dataBindingValue = initialDataBindingValue;
}
public get dataBindingValue() : any {
return this._dataBindingValue;
}
public set dataBindingValue(val : any) {
this._dataBindingValue = val;
if (this.notifyOfChangeHandler != null) {
MyAngularUtils.callLater(this.notifyOfChangeHandler, this._dataBindingValue);
}
}
public unselectRadioButton(valueOfOneRadioButton : any) {
//
// Warning: This method probably never or almost never should be needed.
// Setting the selected radio button to unselected probably should be avoided, since
// the result will be that no radio button will be selected. That is
// typically not how radio buttons work. But we allow it here.
// Be careful in its use.
//
if (valueOfOneRadioButton == this._dataBindingValue) {
console.warn("Setting radio button group value to null");
this.dataBindingValue = null;
}
}
};
Класс переключателей
export class UIRadioButtonControlModel {
public enabled : boolean = true;
public visible : boolean = true;
constructor(public readonly debugName : string,
public readonly MY_DATA_BINDING_VALUE : any,
private readonly group : UIRadioButtonGroupModel,
) {
}
public get selected() : boolean {
return (this.group.dataBindingValue == this.MY_DATA_BINDING_VALUE);
}
public set selected(doSelectMe : boolean) {
if (doSelectMe) {
this.group.dataBindingValue = this.MY_DATA_BINDING_VALUE;
} else {
this.group.unselectRadioButton(this.MY_DATA_BINDING_VALUE);
}
}
}
Ответ 15
Пример листинга радио Angular 8:
Источник Ссылка
![enter image description here]()
Ответ JSON
[
{
"moduleId": 1,
"moduleName": "Employee",
"subModules":[
{
"subModuleId": 1,
"subModuleName": "Add Employee",
"selectedRightType": 1,
},{
"subModuleId": 2,
"subModuleName": "Update Employee",
"selectedRightType": 2,
},{
"subModuleId": 3,
"subModuleName": "Delete Employee",
"selectedRightType": 3,
}
]
},
{
"moduleId": 2,
"moduleName": "Company",
"subModules":[
{
"subModuleId": 4,
"subModuleName": "Add Company",
"selectedRightType": 1,
},{
"subModuleId": 5,
"subModuleName": "Update Company",
"selectedRightType": 2,
},{
"subModuleId": 6,
"subModuleName": "Delete Company",
"selectedRightType": 3,
}
]
},
{
"moduleId": 3,
"moduleName": "Tasks",
"subModules":[
{
"subModuleId": 7,
"subModuleName": "Add Task",
"selectedRightType": 1,
},{
"subModuleId": 8,
"subModuleName": "Update Task",
"selectedRightType": 2,
},{
"subModuleId": 9,
"subModuleName": "Delete Task",
"selectedRightType": 3,
}
]
}
]
HTML-шаблон
<div *ngFor="let module of modules_object">
<div>{{module.moduleName}}</div>
<table width="100%">
<thead>
<tr>
<th>Submodule</th>
<th>
<input type="radio" name="{{module.moduleName}}_head_radio" [(ngModel)]="module.selHeader" (change)="selAllColumn(module)" [value]="1"> Read Only
</th>
<th>
<input type="radio" name="{{module.moduleName}}_head_radio" [(ngModel)]="module.selHeader" (change)="selAllColumn(module)" [value]="2"> Read Write
</th>
<th>
<input type="radio" name="{{module.moduleName}}_head_radio" [(ngModel)]="module.selHeader" (change)="selAllColumn(module)" [value]="3"> No Access
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let sm of module.subModules">
<td>{{sm.subModuleName}}</td>
<td>
<input type="radio" [checked]="sm.selectedRightType == '1'" [(ngModel)]="sm.selectedRightType" name="{{sm.subModuleId}}_radio" [value]="1">
</td>
<td class="cl-left">
<input type="radio" [checked]="sm.selectedRightType == '2'" [(ngModel)]="sm.selectedRightType" name="{{sm.subModuleId}}_radio" [value]="2">
</td>
<td class="cl-left">
<input type="radio" [checked]="sm.selectedRightType == '3'" [(ngModel)]="sm.selectedRightType" name="{{sm.subModuleId}}_radio" [value]="3">
</td>
</tr>
</tbody>
</table>
</div>
Ответ 16
Это может быть неправильное решение, но это вариант, который, возможно, поможет кому-то.
До сих пор я получал значение radioButtons, используя метод (click), например:
<input type="radio" name="options" #male (click)="onChange(male.value)">Male
<input type="radio" name="options" #female (click)="onChange(female.value)">Female
и в файле .ts я установил значение предопределенной переменной в значение getter функции onChange
.
Но после поиска я нашел хороший метод, я еще не пробовал, но кажется, что это хорошо, используя ссылку [(ng-model)]
здесь, чтобы github здесь. это использует RadioControlValueAccessor
для радио, а также для флажка. здесь работает # plnkr # для этого метода здесь
.