2017-04-24 4 views
8

Ich bin nicht sicher, die richtige Art zu binden und ein Modell zu aktualisieren, wo die Checkboxen dynamisch generiert werden. (Dies ist ein ASP.NET Core-Projekt mit Angular 2 zunächst mit dem Yeoman-Generator erstellt) Oder ein einfaches Kontrollkästchen für diese Angelegenheit, die ich gerade herausgefunden habe.Bindung von ngModel an dynamische Checkbox Liste: Angular 2/Typescript

Unten ist abgespeckte Code, der eine Einrichtung und Timeslots hat. Jede Einrichtung kann mehrere Zeitschlitze haben. Die Checkbox-Liste für die Zeitfenster wird angezeigt. Die Anfangsdaten zeigen an, dass nur ein Zeitschlitz geprüft werden sollte. Aber wenn ich eine Einrichtung lade, werden alle Zeitschlitze überprüft. Sie sind nicht mit ngModel wie erwartet verbunden.

  1. Wie kann ich es beheben, so dass nur die in den Einrichtungsdaten enthaltenen Zeitfenster überprüft werden und nicht alle?
  2. Wie binde ich das, was überprüft wird, an die Eigenschaft ngModel timeslotids? Muss ich eine Array-Eigenschaft für die Komponente erstellen und diese manipulieren, anstatt mich auf ngModel zu verlassen? (versuchte dies, aber offensichtlich nicht richtig gemacht, so zurück zu dem Code unten)
  3. Ich habe auch ein Problem mit einem einfachen Kontrollkästchen (haselectric) zu binden, weil dies auch nicht abhebt, wenn es sein sollte. Fehle ich einen Import, der das alles reparieren würde?

Code Erläuterung Ich habe zwei Objekte (Objekt und Zeitschlitz) von einem api kommen, die an Schnittstellen I binden.

export interface IFacility { 
    id: number, 
    name: string, 
    haselectric: boolean, 
    timeslotids: number[],  
    timeslots: ITimeslot[] 

} 
export interface ITimeslot { 
    id: number, 
    timeslotname: string  
} 

Dies ist die JSON-Daten für Timeslots:

[{"id":1,"timeslotname":"Daily"},{"id":2,"timeslotname":"Hourly"},{"id":4,"timeslotname":"Market"}] 

Dies ist die JSON-Daten für eine einzelne Einrichtung, bevor sie aktualisiert:

Sie haben in den Eigenschaften der Einfachheit halber deutlich reduziert
{"id":2,"name":"Clements Building","haselectric":true,"timeslotids":[1],"timeslots":[{"id":1,"timeslotname":"Daily"}]} 

Komponente zum Bearbeiten einer Einrichtung (facility.component.html):

<form #form="ngForm" (ngSubmit)="submitForm()" *ngIf="formactive"> 
    <input type="hidden" [(ngModel)]="updatedfacility.id" #id="ngModel" name="id" /> 
    <div class="form-group"> 
     <label for="name">Facility Name *</label> 
     <input type="text" class="form-control input-lg" [(ngModel)]="updatedfacility.name" #name="ngModel" name="name" placeholder="Facility Name *"> 
    </div> 
    <div class="form-group"> 
        <label for="exhibitspaces">Has Electric *</label> 
        <input type="checkbox" class="form-control input-lg" [(ngModel)]="updatedfacility.haselecric" #haselectric="ngModel" name="haselectric"> 
    </div> 
    <div class="form-group"> 
     <label for="timeslots">Select Timeslots Available for Rent *</label> 
     <div *ngIf="dbtimeslots" > 
      <span *ngFor="let timeslot of dbtimeslots" class="checkbox"> 
       <label for="timeslot"> 
        <input type="checkbox" [(ngModel)]="updatedfacility.timeslotids" value="{{timeslot.id}}" name="{{timeslot.id}}" [checked]="updatedfacility.timeslotids.indexOf(timeslot.id)" />{{timeslot.timeslotname}} 
       </label> 
      </span> 
     </div> 
    </div> 
    <button type="submit" class="btn btn-lg btn-default" [disabled]="form.invalid">Update</button> 
</form> 

-Code für die Komponente (facility.component.ts)

import { Component, OnInit, Input, Output, OnChanges, EventEmitter } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { ActivatedRoute, Router } from '@angular/router'; 
import { FormsModule } from '@angular/forms'; 
import { FacilityService } from '../../../services/facility.service'; 
import { TimeslotService } from '../../../services/timeslot.service'; 
import { IFacility } from '../../../services/facility.interface'; 
import { ITimeslot } from '../../../services/timeslot.interface'; 

@Component({ 
    template: require('./facility.component.html') 
}) 
export class FacilityDetailsComponent { 
    facility: IFacility; 
    httpresponse: string; 
    successMessage: string; 
    errormessage: string; 
    showSuccess: boolean = true; 
    showError: boolean = true; 
    formactive: boolean = true; 
    dbtimeslots: ITimeslot[];  


    constructor(
    private _route: ActivatedRoute, 
    private _router: Router, 
    private _facilityservice: FacilityService, 
    private _timeslotservice: TimeslotService 
) {} 

    ngOnInit(): void { 
    this._timeslotservice.getTimeslots().subscribe(timeslots => this.dbtimeslots = timeslots, error => this.errormessage = <any>error); 
    let id = +this._route.snapshot.params['id']; 

    this._facilityservice.getFacility(id) 
     .subscribe(facility => this.facility = facility, 
     error => this.errormessage = <any>error); 

    } 

    submitForm() { 
    //update the facility through the service call 
    this._facilityservice.updateFacility(this.facility) 
     .subscribe(response => { 
      this.httpresponse = response; 
      console.log(this.httpresponse); 
      this.successMessage = "Facility updated!"; 
      this.formactive = false; 
      setTimeout(() => this.formactive = true, 3); 
      this.showSuccess = false; 
     }, 
     error => { 
      this.errormessage = <any>error; 
      this.showError = false; 
     }); 
    }  

}

P. S. Der Grund, warum ich im Facility-Objekt für Timeslots zwei Eigenschaften habe, liegt darin, dass eine Liste von IDs viel einfacher zur Aktualisierung an die API übergeben werden kann. Anstatt vollständige Modelle zu übertragen (Zeitfenster sind größer als das, was ich hier habe und nicht benötigt, um die Datenbank zu aktualisieren). Bitte beachten Sie Kommentare dazu, da es nichts damit zu tun hat, was zu tun ist.

Ich habe diese Frage gefunden ...aber leider, antwortete niemand diesen armen Kerl: ngmodel binding with dynamic array of checkbox in angular2 dies versucht, aber hat nicht funktioniert: Get values from a dynamic checkbox list ich auch versucht Version eine lokale Eigenschaft auf (ändern) Aktualisierung der Checkbox, aber das scheint nicht zu funktionieren entweder: Angular 2: Get Values of Multiple Checked Checkboxes

Antwort

8

Basierend auf НЛО Antwort oben war ich in der Lage, die Lösung für meine Frage zu finden. Vielen Dank.

<div class="form-group"> 
    <label for="timeslots">Select Timeslots Available for Rent *</label> 
    <div *ngIf="dbtimeslots"> 
     <span *ngFor="let timeslot of dbtimeslots" class="checkbox"> 
      <label> 
       <input type="checkbox" value="{{timeslot.id}}" name="{{timeslot.id}}" [checked]="(facility.timeslotids && (-1 !== facility.timeslotids.indexOf(timeslot.id)) ? 'checked' : '')" (change) ="updateSelectedTimeslots($event)" />{{timeslot.timeslotname}} 
      </label> 
     </span> 
    </div> 
</div> 

Dann ist die Funktion auf der Komponente:

updateSelectedTimeslots(event) { 
    if (event.target.checked) { 
      if (this.facility.timeslotids.indexOf(parseInt(event.target.name)) < 0) { 
       this.facility.timeslotids.push(parseInt(event.target.name)); 

      } 
    } else { 
      if (this.facility.timeslotids.indexOf(parseInt(event.target.name)) > -1) 
      { 
       this.facility.timeslotids.splice(this.facility.timeslotids.indexOf(parseInt(event.target.name)), 1);    
      } 
    } 
    //console.log("TimeslotIDs: ", this.facility.timeslotids);  
} 
8

Ich habe einen Code ähnlich dem Ihren (ngFor über alle möglichen Checkboxen, einige von ihnen sollten überprüft werden, Änderungen sollen in einigen Datenstruktur gespeichert werden, die wir nicht durchlaufen), und hier ist, was ich mit:

<md-checkbox 
    *ngFor="let some of availableSomes" 
    name="{{ some }}" 
    checked="{{ data.somes && -1 !== this.data.somes.indexOf(some) ? 'checked' : '' }}" 
    (change)="updateSome($event)"> 
    {{ some }} 
</md-checkbox> 

Hier updateSome:

Auch ich glaube es sollte event.target sein, aber es ist event.source aufgrund des Materials. Eine Art unbeholfene Lösung, aber ich denke, es wird Ihnen helfen, herauszufinden, wie Sie erreichen können, was Sie wollen

+0

Dank viel. Ich werde das ausprobieren und zurück posten. – EHeine

+0

Dies wies mich in die Richtung, die ich brauchte. Ich habe meinen ursprünglichen Beitrag oben mit dem Lösungscode aktualisiert. Vielen Dank! – EHeine

+2

@EHeine froh, dass du es herausgefunden hast. Sie sollten eine funktionierende Lösung als Antwort veröffentlicht haben und sie akzeptieren, aber –

Verwandte Themen