如何管理Augular动态表单中的复选框?

时间:2017-06-20 13:32:04

标签: angular

我在使用Angular 4以动态形式使复选框工作时遇到了一些问题。

在Firefox上,选中该复选框后,我得到的值为'on',而不是true。取消选中后,该值仍然存在且未设置为false''

在Chrome上,它甚至看起来都不起作用......

我已经基于Angular dynamic form tutorial创建了一个示例。

我添加了一个名为question-checkbox.ts的新文件来管理复选框:

import { QuestionBase } from './question-base';

export class CheckboxQuestion extends QuestionBase<boolean> {
  controlType = 'checkbox';
  type: string;

  constructor(options: {} = {}) {
    super(options);
    this.type = 'checkbox';
  }
}

然后,我更新了dynamic-form-question.component.html以使用这种新类型:

<div [formGroup]="form">
  <label [attr.for]="question.key">{{question.label}}</label>
  <div [ngSwitch]="question.controlType">
    <select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
      <option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
    </select>
    <input *ngSwitchDefault [formControlName]="question.key" [id]="question.key" [type]="question.type" />
  </div>
  <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

而且,我已更新了question.service.ts中的数据集:

import { Injectable }       from '@angular/core';
import { DropdownQuestion } from './question-dropdown';
import { QuestionBase }     from './question-base';
import { TextboxQuestion }  from './question-textbox';
import { CheckboxQuestion }  from './question-checkbox';

@Injectable()
export class QuestionService {

  getQuestions() {

    let questions: QuestionBase<any>[] = [

      new DropdownQuestion({
        key: 'brave',
        label: 'Bravery Rating',
        options: [
          { key: 'solid', value: 'Solid' },
          { key: 'great', value: 'Great' },
          { key: 'good', value: 'Good' },
          { key: 'unproven', value: 'Unproven' }
        ],
        order: 3
      }),

      new TextboxQuestion({
        key: 'firstName',
        label: 'First name',
        value: 'Bombasto',
        required: true,
        order: 1
      }),

      new TextboxQuestion({
        key: 'emailAddress',
        label: 'Email',
        type: 'email',
        order: 2
      }),

      new CheckboxQuestion({
        key: 'sideksick',
        label: 'Sidekick',
        order: 3
      })
    ];

    return questions.sort((a, b) => a.order - b.order);
  }
}

最后,我更新了dynamic-form.component.html以显示表单的当前状态:

<div>
  <form [formGroup]="form">
    <div *ngFor="let question of questions" class="form-row">
      <df-question [question]="question" [form]="form"></df-question>
    </div>
  </form>
  <p><strong>Current state</strong><br>{{form.value | json}}</p>
</div>

Example available on Plunker

所以我的问题是:我应该如何在Angular 4动态表单中使用复选框,并能够获得正确的值?

至于为什么我需要使用动态表单,这是因为我基于来自描述它的外部服务的JSON生成我的表单。

1 个答案:

答案 0 :(得分:0)

新答案

似乎有一种非常奇怪的行为会导致Angular 4.x出现此问题。

写这个不起作用:

<input *ngSwitchCase="'checkbox'" [formControlName]="question.key" [id]="question.key" [type]="'checkbox'" />

但写这个确实有效:

<input *ngSwitchCase="'checkbox'" [formControlName]="question.key" [id]="question.key" type="checkbox" />

唯一的区别是我们不使用Angular模板功能([type]="question.type"[attr.type]="question.type"type={{question.type}})来编写type的内容,所以我们只使用HTML中的原生type 这对我来说似乎是个错误......

这里是fix on Plunker

旧答案

上述解决方案是您应该考虑的唯一解决方案。

我从angular2-dynamic-form-checkbox的答案中找到了一个提示。

我错过了文件dynamic-form-question.component.html中的以下部分:[(ngModel)]="question.value" (change)="question.value = ckb.checked" #ckb

<select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
  <option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="question.key" [id]="question.key" [type]="question.type" [(ngModel)]="question.value" (change)="question.value = ckb.checked" #ckb />
<input *ngSwitchDefault [formControlName]="question.key" [id]="question.key" [type]="question.type" />

似乎在动态表单的情况下,复选框不会自动管理,因此我们需要根据复选框的change状态更新checked上的值。< / p>

这里是fix on Plunker