Ich möchte das Optionsfeld in einem Formular mit Angular 2 verwenden
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/>
der Anfangswert von model.options ist 1
beim Laden der Seite wird das erste Optionsfeld nicht aktiviert und die Änderungen sind nicht an das Modell gebunden
Irgendeine Idee ?
verwenden Sie [value] = "1" anstelle von 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/>
Bearbeiten:
Wie von thllbrg vorgeschlagen "Verwenden Sie für angular 2.1+ [(ngModel)]
anstelle von [(ng-model)]
"
Hinweis - Optionsfeldbindung ist jetzt eine unterstützte Funktion ab RC4 - siehe diese Antwort
Optionsfeldbeispiel mit benutzerdefiniertem RadioControlValueAccessor ähnlich CheckboxControlValueAccessor ( Aktualisiert mit 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; }
}
Quelle: https://github.com/angular2-school/angular2-radio-button
Plunker Live-Demo: http://plnkr.co/edit/aggee6An1iHfwsqGoE3q?p=preview
Meine manuelle Problemumgehung, bei der model.options
manuell aktualisiert wird, wenn ein neues Optionsfeld ausgewählt wird:
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' };
}
Diese Plunker demonstriert das oben Genannte sowie die Verwendung einer Schaltfläche zum Ändern des ausgewählten Optionsfelds - d. h. um zu beweisen, dass die Datenbindung bidirektional ist:
<button (click)="model.options = 'one'">set one</button>
Hier ist die beste Möglichkeit, Optionsfelder in Angular2 zu verwenden. Es ist nicht erforderlich, das (Klick) -Ereignis oder einen RadioControlValueAccessor zu verwenden, um den Wert der gebundenen Eigenschaft zu ändern. Die Einstellung der Eigenschaft [checked] erledigt den Trick.
<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/>
Ich habe ein Beispiel für die Verwendung von Optionsfeldern veröffentlicht: Angular 2: Erstellen von Optionsfeldern aus Enum und Hinzufügen einer bidirektionalen Bindung? Funktioniert ab Angular 2 RC5.
Dieses Problem wurde in Version Angular 2.0.0-rc.4 bzw. in Formularen behoben.
Fügen Sie "@angular/forms": "0.2.0"
in package.json ein.
Erweitern Sie dann Ihr bootstrap in main. Relevanter Teil:
...
import { AppComponent } from './app/app.component';
import { disableDeprecatedForms, provideForms } from '@angular/forms';
bootstrap(AppComponent, [
disableDeprecatedForms(),
provideForms(),
appRouterProviders
]);
Ich habe dies in .html und funktioniert einwandfrei: 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>
Ich habe nach der richtigen Methode gesucht, um mit diesen Optionsfeldern umzugehen. Dies ist ein Beispiel für eine Lösung, die ich hier gefunden habe:
<tr *ngFor="let entry of entries">
<td>{{ entry.description }}</td>
<td>
<input type="radio" name="radiogroup"
[value]="entry.id"
(change)="onSelectionChange(entry)">
</td>
</tr>
Beachten Sie das onSelectionChange, das das aktuelle Element an die Methode übergibt.
[value] = "item" mit * ngFor funktioniert auch mit reaktiven Formularen in Angular 2 und 4
<label *ngFor="let item of items">
<input type="radio" formControlName="options" [value]="item">
{{item}}
</label>`
Das folgende Problem hat mein Problem behoben. Fügen Sie möglicherweise Funkinput in das form
-Tag ein und verwenden Sie das [value]
-Tag, um den Wert anzuzeigen.
<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>
Hier ist eine Lösung, die für mich funktioniert. Hierbei handelt es sich um eine Optionsfeldbindung - jedoch nicht um eine Bindung an Geschäftsdaten, sondern um eine Bindung an den Status des Optionsfelds. Es ist wahrscheinlich NICHT die beste Lösung für neue Projekte, aber für mein Projekt geeignet. In meinem Projekt ist eine Menge Code in einer anderen Technologie geschrieben, die ich nach Angular portiere. Der alte Code folgt einem Muster, bei dem der Code sehr daran interessiert ist, jedes Optionsfeld zu untersuchen, um festzustellen, ob es sich um das ausgewählte handelt. Die Lösung ist eine Variation der Click-Handler-Lösungen, von denen einige bereits bei Stack Overflow erwähnt wurden. Der Mehrwert dieser Lösung kann sein:
- Funktioniert mit dem Muster des alten Codes, mit dem ich arbeiten muss.
- Ich habe eine Hilfsklasse erstellt, um zu versuchen, die Anzahl der "if" -Anweisungen im Click-Handler zu verringern und eine beliebige Gruppe von Optionsfeldern zu behandeln.
Diese Lösung beinhaltet
- Verwenden Sie für jedes Optionsfeld ein anderes Modell.
- Festlegen des Attributs "Aktiviert" mit dem Modell des Optionsfelds.
- Übergeben des Modells des angeklickten Optionsfelds an die Hilfsklasse.
- Die Helferklasse sorgt dafür, dass die Modelle auf dem neuesten Stand sind.
- Bei "Submit Time" kann der alte Code den Status der Optionsfelder überprüfen, um durch Untersuchen der Modelle festzustellen, welches ausgewählt ist.
Beispiel:
<input type="radio"
[checked]="maleRadioButtonModel.selected"
(click)="radioButtonGroupList.selectButton(maleRadioButtonModel)"
...
<input type="radio"
[checked]="femaleRadioButtonModel.selected"
(click)="radioButtonGroupList.selectButton(femaleRadioButtonModel)"
...
Wenn der Benutzer auf ein Optionsfeld klickt, wird die selectButton-Methode der Hilfsklasse aufgerufen. Es wird das Modell für das Optionsfeld übergeben, auf das geklickt wurde. Die Hilfsklasse setzt das boolesche Feld "selected" des übergebenen Modells auf "true" und das Feld "selected" aller anderen Optionsfeldmodelle auf "false".
Während der Initialisierung muss die Komponente eine Instanz der Hilfsklasse mit einer Liste aller Optionsfeldmodelle in der Gruppe erstellen. Im Beispiel wäre "radioButtonGroupList" eine Instanz der Hilfsklasse, deren Code wie folgt lautet:
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");
}
}
}
So sehr diese Antwort je nach Anwendungsfall möglicherweise nicht die beste ist, funktioniert sie. Anstatt die Optionsschaltfläche für eine männliche und weibliche Auswahl zu verwenden, funktioniert die Verwendung von <select> </select>
perfekt, sowohl zum Speichern als auch zum Bearbeiten.
<select formControlName="gender" name="gender" class="">
<option value="M">Male</option>
<option value="F">Female</option>
</select>
Das oben Genannte sollte für die Bearbeitung mit FormGroup mit patchValue
ausreichen. Zum Erstellen können Sie [(ngModel)]
anstelle von formControlName
verwenden. Funktioniert noch.
Aufgrund der Installationsarbeiten für das Optionsfeld "Eins" habe ich mich stattdessen für die Auswahl entschieden. Optisch und UX-weise scheint es nicht das Beste zu sein, aber vom Standpunkt eines Entwicklers ist es eine Tonne einfacher.
Ich habe eine Version erstellt, indem ich nur ein Klickereignis auf die geladenen Elemente verwendete und den Wert der Auswahl in die Funktion "getSelection" übergab und das Modell aktualisierte.
In Ihrer Vorlage:
<ul>
<li *ngFor="let p of price"><input type="radio" name="price" (click)="getValue(price.value)" value="{{p}}" #price> {{p}}
</li>
</ul>
Deine Klasse:
export class App {
price:string;
price = ["1000", "2000", "3000"];
constructor() { }
model = new SomeData(this.price);
getValue(price){
this.model.price = price;
}
}
Siehe Beispiel: https://plnkr.co/edit/2Muje8yvWZVL9OXqG0pW?p=info
Einfachste Lösung und Problemumgehung:
<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
}