it-swarm.com.de

Angular2 - Optionsfeldbindung

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 ?

119
Mourad Zouabi

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)]"

102
Atal Kishore

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

61
Nidin Vinayakan

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>
42
Mark Rajcok

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.

36

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>
18
Zolcsi

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.

6
Pini Cheyni

[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>`
4
Colleen Purcell

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"> &nbsp; {{ item.name }}
    </div>
</form>
4
rc.adhikari

Radioeingang wird anscheinend noch nicht unterstützt. Es sollte einen Radio-Input-Value-Accessor geben (ähnlich wie bei der Checkbox one , bei dem 'checked' attr here gesetzt ist), aber ich habe keinen gefunden. Also habe ich eine implementiert; Sie können es heraus überprüfen hier .

4
barbatus

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:

  1. Funktioniert mit dem Muster des alten Codes, mit dem ich arbeiten muss.
  2. 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

  1. Verwenden Sie für jedes Optionsfeld ein anderes Modell.
  2. Festlegen des Attributs "Aktiviert" mit dem Modell des Optionsfelds.
  3. Übergeben des Modells des angeklickten Optionsfelds an die Hilfsklasse.
  4. Die Helferklasse sorgt dafür, dass die Modelle auf dem neuesten Stand sind.
  5. 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");
    }
  }
}
3
user2367418

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.

1
Rexford

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

1
MrLukrative

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
}
1
Jacek Pudysz