Angular 嵌套动态表单
Angular nested dynamic form
如何按照 angular.io 文档中的方式制作嵌套表格:
https://stackblitz.com/angular/pbdkbbnmrdg
目标是在名为 "details" 的子表单组中有两个来自 question.service.ts 的 DropdownQuestion 以及现在父表单中的所有其他内容......所以最后看起来像这样:
{
"firstName":"Bembasto",
"email":"something@email.com",
"details": {
"dropdown1":{
},
"dropdown2":{
}
}
}
Uros,您需要了解代码如何创建 FormGroup 以及如何创建输入。
我们有一个用于
的复杂对象
- 创建表格
- 显示输入
首先我们要创建一个新的控件类型question-group
import { QuestionBase } from './question-base';
export class GroupQuestion extends QuestionBase<string> {
controlType = 'group';
type: string;
constructor(options: {} = {}) {
super(options);
}
}
并向 question-base
添加一个新属性
questions:any[];
//and change the constructor to allow give value
constructor(options: {
value?: T,
...
questions?:any[]
} = {}) {
this.value = options.value;
...
this.questions = options.questions || [];
}
看看代码是如何创建表单的。它是在 question-control.service 中制作的。将函数更改为 FormGroup 以考虑类型控件 "group"
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
group[question.key] = (question.controlType=='group')?
this.toFormGroup(question.questions)
:question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
});
return new FormGroup(group);
}
是的,我们正在使用递归函数。我们的想法是我们将有一个问题对象,例如
let questions: QuestionBase<any>[] = [
new DropdownQuestion({
...
}),
new TextboxQuestion({
...
})
, new GroupQuestion(
{
key: 'details',
label: 'Details',
order: 2,
questions: [
new TextboxQuestion({
...
}),
new DropdownQuestion({
...
})
]
}
)
];
好吧,有了这些更改,我们还没有如何创建 formGroup 但是,我们如何显示输入?
之前,我们将更改 dinamic-form-component 以允许将 "form"
作为参数传递
@Input() form: FormGroup;
subGroup:boolean=true;
ngOnInit() {
if (!this.form)
{
this.form = this.qcs.toFormGroup(this.questions);
this.subGroup=false;
}
}
我们添加了一个新属性 "subGroup" 来指示是否是子组。所以,我们可以隐藏按钮 "submit".
最后我们要更改 dynamic-form-question.component.html 以考虑 "group-questions"
<div [formGroup]="form">
<label [attr.for]="question.key">{{question.label}}</label>
<div [ngSwitch]="question.controlType">
<input *ngSwitchCase="'textbox'" ...>
<select *ngSwitchCase="'dropdown'" ...>
</select>
<div *ngSwitchCase="'group'" [formGroupName]="question.key">
<app-dynamic-form [form]="form.get(question.key)"
[questions]="question.questions"></app-dynamic-form>
</div>
</div>
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>
是的,如果我们有 group-question,我们会显示 app-dinamic-form 通行证,形式为 "form.get(question.key)"。这就是我们更改 dinamic-form-component 的原因:允许传递一个 formGroup 并且只在不传递值的情况下创建一个新表单。
在这个 stackblitz 中是完整的例子
注意:我个人不喜欢创建 formGroup 的组件。我喜欢在 main.component 中创建 formGroup 并作为参数传递
在 this other stackblitz 中探索这个想法。 app-component 有一个 ngOnInit 可以进行两次调用
ngOnInit()
{
this.questions = this.service.getQuestions();
this.form=this.qcs.toFormGroup(this.questions);
}
我们需要手动给 dinamic-form 的属性 "subGroup" 赋值
如何按照 angular.io 文档中的方式制作嵌套表格:
https://stackblitz.com/angular/pbdkbbnmrdg
目标是在名为 "details" 的子表单组中有两个来自 question.service.ts 的 DropdownQuestion 以及现在父表单中的所有其他内容......所以最后看起来像这样:
{
"firstName":"Bembasto",
"email":"something@email.com",
"details": {
"dropdown1":{
},
"dropdown2":{
}
}
}
Uros,您需要了解代码如何创建 FormGroup 以及如何创建输入。
我们有一个用于
的复杂对象- 创建表格
- 显示输入
首先我们要创建一个新的控件类型question-group
import { QuestionBase } from './question-base';
export class GroupQuestion extends QuestionBase<string> {
controlType = 'group';
type: string;
constructor(options: {} = {}) {
super(options);
}
}
并向 question-base
添加一个新属性questions:any[];
//and change the constructor to allow give value
constructor(options: {
value?: T,
...
questions?:any[]
} = {}) {
this.value = options.value;
...
this.questions = options.questions || [];
}
看看代码是如何创建表单的。它是在 question-control.service 中制作的。将函数更改为 FormGroup 以考虑类型控件 "group"
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
group[question.key] = (question.controlType=='group')?
this.toFormGroup(question.questions)
:question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
});
return new FormGroup(group);
}
是的,我们正在使用递归函数。我们的想法是我们将有一个问题对象,例如
let questions: QuestionBase<any>[] = [
new DropdownQuestion({
...
}),
new TextboxQuestion({
...
})
, new GroupQuestion(
{
key: 'details',
label: 'Details',
order: 2,
questions: [
new TextboxQuestion({
...
}),
new DropdownQuestion({
...
})
]
}
)
];
好吧,有了这些更改,我们还没有如何创建 formGroup 但是,我们如何显示输入? 之前,我们将更改 dinamic-form-component 以允许将 "form"
作为参数传递 @Input() form: FormGroup;
subGroup:boolean=true;
ngOnInit() {
if (!this.form)
{
this.form = this.qcs.toFormGroup(this.questions);
this.subGroup=false;
}
}
我们添加了一个新属性 "subGroup" 来指示是否是子组。所以,我们可以隐藏按钮 "submit".
最后我们要更改 dynamic-form-question.component.html 以考虑 "group-questions"
<div [formGroup]="form">
<label [attr.for]="question.key">{{question.label}}</label>
<div [ngSwitch]="question.controlType">
<input *ngSwitchCase="'textbox'" ...>
<select *ngSwitchCase="'dropdown'" ...>
</select>
<div *ngSwitchCase="'group'" [formGroupName]="question.key">
<app-dynamic-form [form]="form.get(question.key)"
[questions]="question.questions"></app-dynamic-form>
</div>
</div>
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>
是的,如果我们有 group-question,我们会显示 app-dinamic-form 通行证,形式为 "form.get(question.key)"。这就是我们更改 dinamic-form-component 的原因:允许传递一个 formGroup 并且只在不传递值的情况下创建一个新表单。
在这个 stackblitz 中是完整的例子
注意:我个人不喜欢创建 formGroup 的组件。我喜欢在 main.component 中创建 formGroup 并作为参数传递
在 this other stackblitz 中探索这个想法。 app-component 有一个 ngOnInit 可以进行两次调用
ngOnInit()
{
this.questions = this.service.getQuestions();
this.form=this.qcs.toFormGroup(this.questions);
}
我们需要手动给 dinamic-form 的属性 "subGroup" 赋值