angular - 复选框值在反应形式中没有变化
问题描述
我在响应式表单的帮助下从 json 文件生成表单。表单的生成正常工作,但我面临的问题是 - 当我第一次在 mozila 中单击复选框时,它的值变为“on”。但是当我取消选中它时,它没有发生任何事情,它的值仍然是“开”,应该是“关或假”。在点击 chrome 中什么都没有发生。
app.components.ts
import { Component } from '@angular/core';
import { QuestionControlService } from './question-control.service';
import GxData from './gx.json';
@Component({
selector: 'app-root',
template: `
<div>
<app-dynamic-form [questions]="questions"></app-dynamic-form>
</div>
`,
providers: []
})
export class AppComponent{
questions: any[];
constructor() {
this.questions = GxData;
}
}
动态form.components.ts
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { QuestionControlService } from '../question-control.service';
import SbbData from '../sbb.json';
import GxData from '../gx.json';
@Component({
selector: 'app-dynamic-form',
templateUrl: './dynamic-form.component.html',
providers: [QuestionControlService]
})
export class DynamicFormComponent implements OnInit {
@Input() questions: any[] = [];
form: FormGroup;
payLoad = '';
constructor(private qcs: QuestionControlService) { }
ngOnInit() {
this.form = this.qcs.toFormGroup(this.questions);
}
callGx() {
this.questions = GxData;
this.form = this.qcs.toFormGroup(this.questions);
}
callSbb() {
this.questions = SbbData;
this.form = this.qcs.toFormGroup(this.questions);
}
onSubmit() {
this.payLoad = JSON.stringify(this.form.value);
console.log(JSON.parse(this.payLoad));
}
}
动态form.component.html
<div class="search_box">
<form (ngSubmit)="onSubmit()" [formGroup]="form">
<button type="button" (click)="callSbb()">SBB</button>
<button type="button" (click)="callGx()">GX</button>
<div *ngFor="let question of questions" class="form-row">
<app-question [question]="question" [form]="form"></app-question>
</div>
<div class="form-row">
<button type="submit" [disabled]="!form.valid">Save</button>
</div>
</form>
<div *ngIf="payLoad" class="form-row">
<strong>Saved the following values</strong><br>{{payLoad}}
</div>
</div>
{{form.value |json}}
问题-control.service.ts
import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: any[]) {
let group: any = {};
questions.forEach(question => {
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
});
return new FormGroup(group);
}
}
动态形式question.component.ts
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
// import { QuestionBase } from '../question-base';
@Component({
selector: 'app-question',
templateUrl: './dynamic-form-question.component.html'
})
export class DynamicFormQuestionComponent {
@Input() question: any;
@Input() form: FormGroup;
get isValid() { return this.form.controls[this.question.key].valid; }
}
动态表单question.component.html
<div [formGroup]="form">
<div [ngSwitch]="question.controlType" class="checkbox_wrapper">
<input *ngSwitchCase="'textbox'" [formControlName]="question.key" [id]="question.key" [type]="question.type" name="{{question.name}}">
<label [attr.for]="question.key">{{question.label}}</label>
<select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key" name = "{{question.name}}" >
<option *ngFor="let opt of question.options" [attr.value]="opt.key" [selected]="opt.select">{{opt.value}}</option>
</select>
</div>
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>
两个 json 文件看起来像
[
{
"key": "Context",
"label": "Context",
"required": false,
"order": 1,
"controlType": "textbox",
"name": "Context",
"type": "checkbox"
},
{
"key": "contextopt",
"label": "",
"required": false,
"order": 2,
"controlType": "dropdown",
"name": "contextopt",
"options": [
{
"key": "All Context",
"value": "All Context",
"select": true
},
{
"key": "aaa",
"value": "aaa"
},
{
"key": "bb",
"value": "bb"
},
{
"key": "Other",
"value": "Other"
}
]
},
{
"key": "Movement",
"label": "Movement",
"required": false,
"order": 3,
"controlType": "textbox",
"name": "Movement",
"type": "checkbox"
}
]
解决方案
更新问题是当你写[type]="question.type"
和 question.type="checkbox" 时。看起来 Angular 不喜欢这个复选框,(但喜欢使用电子邮件、号码......)
替换ng*SwitchCase="'textbox'"
为
<ng-container *ngSwitchCase="'textbox'">
<input *ngIf="question.type!='checkbox'" [formControlName]="question.key"
[id]="question.key" [type]="question.type">
<input *ngIf="question.type=='checkbox'" [formControlName]="question.key"
[id]="question.key" type="checkbox">
</ng-container>
你可以成为stackblitz中的榜样
其他想法是创建一个新类型,“复选框”和 switchCase 的新选项新的 CheckBoxQuestion 是文本框的副本
export class CheckBoxQuestion extends QuestionBase<boolean> {
controlType = 'checkbox';
constructor(options: {} = {}) {
super(options);
}
}
和 switchCase 添加
<input *ngSwitchCase="'checkbox'" type="checkbox" [formControlName]="question.key">
,在stackblitz中你有两种情况
注意:您正在创建一个大循环
<div [formGroup]="form">
<input formGroupName="question.key">
</div>
<div [formGroup]="form">
<input formGroupName="question.key">
</div>
...
我建议,将您的 dynamic-form-question.component.html 更改为简单地创建
<div>
<input [formControl]="form.get(question.key)" ..>
</div>
是的,将组合 [formGroup]="form"..formControlName=".." 更改为 [formControl]="form.get(..")。
推荐阅读
- ionic-framework - 需要一份将 ionic v1 应用程序数据备份到 Google Drive 的明确指南
- python - 仅比较字典列表中的某些字典键值 Python
- c++ - 移动包含值的对象
- android - Dotfuscator CE 无法从 Xamarin Nuget 包中找到程序集
- angular - CI/CD sed 命令与为另一个环境构建
- oracle - 如何编写一个 PL SQL 过程来使用游标显示表 Employee 中的所有记录?
- python - Textblob 过度概括文本并将其归类为中性
- django - /student/ HTTP 状态码的 TypeError 必须是整数
- python - 如何在我的代码中使用存储在 GridDB 中的模型?
- c# - 如何使用 FFMpegCore 从视频文件中读取 System.Drawing.Bitmaps?