2017-04-24 18 views
8

Nie jestem pewien, w jaki sposób powiązać i zaktualizować model, w którym pola wyboru są generowane dynamicznie. (Jest to projekt ASP.NET Core z Angular 2 początkowo utworzony przy użyciu generatora Yeoman) lub prosty checkbox dla tej sprawy, którą właśnie odkryłem.Wiązanie ngModel z dynamiczną listą wyboru: Angular 2/Maszynopis

Poniżej przedstawiono uproszczony kod, który zawiera obiekt i szczeliny czasowe. Każdy obiekt może mieć wiele szczelin czasowych. Pole wyboru przedziału czasowego wyświetla się dobrze. Początkowe dane wskazują, że należy sprawdzić tylko jedną szczelinę czasową. Ale kiedy ładuję obiekt, wszystkie szczeliny czasowe są sprawdzane. Nie są wiążące dla ngModel, jak się spodziewałem.

  1. Jak to naprawić, aby sprawdzać tylko szczeliny czasowe zawarte w danych obiektu, a nie wszystkie?
  2. Jak powiązać to, co jest zaznaczone z właściwością timestids ngModel? Czy muszę utworzyć właściwość tablicy na komponencie i manipulować nią, zamiast polegać na ngModel? (próbowałem tego, ale najwyraźniej nie zrobiłem tego dobrze, więc wróciłem do kodu poniżej)
  3. Wydaje mi się również, że problem wiąże się z prostym polem wyboru (haselectric), ponieważ to też nie jest odliczane, kiedy powinno być. Czy brakuje mi importu, który naprawiłby to wszystko?

KOD WYJAŚNIENIE Mam dwa obiekty (obiekt i szczelinę czasową) pochodzące z api, które wiążę z interfejsami. Zostały one znacznie zmniejszone właściwości dla uproszczenia:

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

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

to dane JSON do szczelin:

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

to dane JSON dla pojedynczego instrumentu przed ich aktualizacja:

{"id":2,"name":"Clements Building","haselectric":true,"timeslotids":[1],"timeslots":[{"id":1,"timeslotname":"Daily"}]} 

Komponent do edycji obiektu (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> 

Kod składnika (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. Powodem, dla którego mam dwie właściwości obiektu obiektu dla szczelin czasowych, jest fakt, że lista identyfikatorów jest łatwiejsza do przejścia do interfejsu API w celu aktualizacji. Zamiast przechodzić przez pełne modele (szczeliny czasowe są większe niż to, co mam tutaj i nie muszę aktualizować bazy danych). Prosimy o komentarze na ten temat, ponieważ nie ma to związku z tym, co należy osiągnąć.

Znalazłem to pytanie ...ale niestety, nikt nie odpowiedział na tego biedaka: ngmodel binding with dynamic array of checkbox in angular2 Próbowałem tego, ale nie działał: Get values from a dynamic checkbox list Próbowałem również wersji aktualizacji lokalnej nieruchomości na (zmiana) pola wyboru, ale nie wydaje się również działać: Angular 2: Get Values of Multiple Checked Checkboxes

Odpowiedz

8

Na podstawie powyższej odpowiedzi dałem mi możliwość znalezienia rozwiązania mojego pytania. Dziękuję НЛО.

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

Następnie funkcja na części:

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

Mam kod podobny do twojego (ngFor nad wszystkimi możliwymi polami wyboru, niektóre z nich powinny być zaznaczone, zmiany mają zostać zapisane w niektórych strukturach danych, które nie są iterowane) i oto co wymyślę:

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

Oto updateSome:

updateSome(event) { 
    if (-1 !== this.availableSkills.indexOf(event.source.name)) { 
    if (event.checked) { 
     this.data.somes.push(event.source.name); 
    } else { 
     this.data.somes.splice(this.data.somes.indexOf(event.source.name), 1); 
    } 
    } 
} 

Ponadto uważam, że powinien być event.target, ale jest to event.source ze względu na materiał. Coś niezręcznego rozwiązania, ale myślę, że pomoże ci to ustalić, w jaki sposób możesz osiągnąć to, czego chcesz.

+0

Dzięki dużo. Chcemy to wypróbować i odesłać z powrotem. – EHeine

+0

To wskazało mi kierunek, w którym potrzebowałem. Zaktualizowałem mój pierwotny post powyżej za pomocą kodu rozwiązania. Dziękuję Ci bardzo! – EHeine

+2

@ Heheine cieszę się, że to wymyśliłeś. Powinieneś opublikować rozwiązanie robocze jako odpowiedź i zaakceptować je jako –

Powiązane problemy