将ngModel绑定到动态复选框列表:Angular 2/Typescript [英] Binding ngModel to Dynamic Checkbox List : Angular 2 / Typescript

查看:82
本文介绍了将ngModel绑定到动态复选框列表:Angular 2/Typescript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定绑定和更新动态生成复选框的模型的正确方法. (这是一个最初使用Yeoman生成器创建的Angular 2的ASP.NET Core项目),或者我刚刚发现的一个简单复选框.

I'm not sure the proper way to bind and update a model where the checkboxes are dynamically generated. (This is a ASP.NET Core project with Angular 2 initially created using the Yeoman generator) Or a simple checkbox for that matter I have just found out.

下面是精简的代码,其中包含一个功能和时隙.每个设施可以具有多个时隙.时间段复选框列表显示正常.初始数据指示仅应检查一个时隙.但是,当我加载设施时,将检查所有时隙.他们没有像我预期的那样与ngModel绑定.

Below is stripped down code, which has a facility and timeslots. Each facility can have multiple timeslots. The timeslot checkbox list displays fine. The initial data indicates only one timeslot should be checked. But when I load up a facility, all the timeslots are checked. They aren't binding with ngModel as I expected.

  1. 如何解决它,以便仅检查设施数据中包括的时隙而不是全部?
  2. 如何将检查的内容绑定到ngModel timeslotids属性?我是否需要在组件上创建一个数组属性并对其进行操作,而不是依赖于ngModel? (尝试过此操作,但显然没有正确执行,因此恢复为下面的代码)
  3. 我似乎在绑定到一个简单的复选框(haselectric)时也遇到了问题,因为这也没有在应有的时间进行检查.我错过了可以解决所有问题的导入吗?

代码说明 我有两个对象(功能和时间段)来自我绑定到接口的api.为了简单起见,它们的属性已大大降低:

CODE EXPLANATION I have two objects (facility and timeslot) coming from an api which I bind to interfaces. They have been significantly reduced in properties for simplicity's sake:

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

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

这是时间段的JSON数据:

This is the JSON data for Timeslots:

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

这是在更新之前单个设施的JSON数据:

This is the JSON data for a single Facility prior to being updated:

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

用于编辑设施的组件(facility.component.html):

Component for editing a facility (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>

组件代码(facility.component.ts)

Code for the component (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.我在用于时隙的设施对象中具有两个属性的原因是,因为ID列表很容易传递给API进行更新.而不是传递完整的模型(时隙比我在这里使用的要大,并且不需要更新数据库).请保留对此的评论,因为它与需要完成的任务无关.

P.S. The reason I have a two properties in the facility object for timeslots is because a list of id's is much easier to pass through to the API for updating. Rather than passing full models (timeslots is larger than what I have here and not needed to update the database). Please reserve comments on that as it's unrelated to what needs to be accomplished.

我发现了这个问题...但是可悲的是,没有人回答这个可怜的家伙:从动态复选框列表中获取值 我还尝试了在复选框的(更改)上更新本地属性的版本,但这似乎也不起作用:

I found this question...but sadly, no one answered this poor fellow: ngmodel binding with dynamic array of checkbox in angular2 Tried this but didn't work: Get values from a dynamic checkbox list I also tried version of updating an local property on (change) of the checkbox but that didn't seem to work either: Angular 2: Get Values of Multiple Checked Checkboxes

推荐答案

基于上面的НЛО答案,我能够找出问题的解决方案.谢谢НЛО.

Based on НЛО answer above I was able to figure out the solution to my question. Thank you НЛО.

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

然后在组件上执行该功能:

Then the function on the component:

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);    
}

这篇关于将ngModel绑定到动态复选框列表:Angular 2/Typescript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆