【发布时间】:2017-08-08 03:42:34
【问题描述】:
我已经使用 angular2 几个星期了,我正在尝试为系统设置页面创建动态表单。 目标:让 api 返回任意数量的表单,在选项卡内构建表单,表单可以具有任何 type 字段,并使用默认或以前保存的数据填充这些表单,然后修改和保存。
有效的方法:使用任意数量的输入字段创建任意数量的表单。 我需要用数据填充表单的帮助。 这是从 api 调用生成的项目。需要填充这些猫科动物的数据我需要一个单独的 api 调用。 请记住,每个表单都可以有多个这些输入
<li [formGroup]="form" class="form-control-item">
<div [ngSwitch]="item.controlType">
<div *ngSwitchCase="'text'">
<label class="text-lable " [for]="item.key">{{item.label}}</label>
<div [ngSwitch]="item.controlType">
<input [formControlName]="item.key" [id]="item.key" [type]="item.type" class="validate form-control input-lg" input name="{{ name }}" ng-model="name">
</div>
</div>
<div *ngSwitchCase="'checkbox'">
<label class="label-checkbox" [for]="item.key">{{item.label}}
<input [formControlName]="item.key" name="{{ item.key }}" ng-model="name" type="checkbox" class="validate form-control checkbox-with-label" >
</label>
</div>
<!--Needs testing with appropriate data-->
<!--<div *ngSwitchCase="'dropdown'">-->
<!--<label [for]="item.key">{{item.label}}</label>-->
<!--<input [formControlName]="item.key" [id]="item.key" [type]="item.type" class="validate form-control input-lg">-->
<!--<select [id]="item.key" [formControlName]="item.key">-->
<!--<option *ngFor="let opt of item.options" [value]="opt.key">{{opt.value}}</option>-->
<!--</select>-->
<!--</div>-->
<div *ngSwitchCase="'radio'">
<label [for]="item.key">{{item.label}}</label>
<input [formControlName]="item.key" [id]="item.key" [type]="item.type" class="validate form-control radio" name="{{ item.key }}" ng-model="name">
</div>
<div *ngSwitchCase="'password'">
<label [for]="item.key">{{item.label}}</label>
<input [formControlName]="item.key" [id]="item.key" [type]="item.type" class="validate form-control input-lg" name="{{ item.key }}" ng-model="name">
</div>
</div>
<div class="errorMessage" *ngIf="!isValid">{{item.label}} is required</div>
这里是调用上述内容的组件:
@Component({
selector: 'dynamic-form',
templateUrl: 'dynamic-form.component.html',
styleUrls: ['./dynamic-form.component.scss']
})
export class DynamicFormComponent implements OnChanges {
@Input() items: DynamicFormItemBase<any>[] = [];
form: FormGroup;
payLoad = '';
constructor(){
}
ngOnChanges(){
this.form = this.toFormGroup(this.items);
}
ngOnInit(){
this.form = this.toFormGroup(this.items);
}
onSubmit() {
this.payLoad = JSON.stringify(this.form.value);
}
private toFormGroup(items: DynamicFormItemBase<any>[] ) {
let group: any = {};
items.forEach(item => {
if(item.value.items){
// console.log('has an internal item');
}
group[item.key] = new FormControl(item.value || '', item.required ? Validators.required : null);
// console.log(item.value, 'has an internal item');
});
return new FormGroup(group);
}
}
再次澄清一下,我调用了一个 api 来获取将有多少表单及其名称。然后一个 api 调用按名称获取每个表单的布局(来自第一个 api 调用)。所有表格都可以构建。然后我有第三个 api 调用,它返回该表单的配置数据;我需要将此数据绑定到每个特定表单。
我无法创建典型的 ng-model="name" name="ng-model" #name 数据绑定方式。或者至少我不知道如何动态实现它。
<tab class="{{module.name}}-tab" *ngFor="let module of Modules; let i =
index" heading="{{module.displayName}}" (select)="beforeChange(module.name)">
<div class="dynamic-form" >
<dynamic-form [items]="items" >Loading...</dynamic-form>
</div>
其中 items 是从 api 返回的。它的结构如下: 第一次调用是这样的
ModuleList [{"name":"moduleName","displayName":"Module Name","enabled":true}]
其他一些不相关的代码运行,然后使用 maduleName 的参数进行 api 调用以返回布局
Array[
0:Array[
0:DynamicFormItemBase[
controlType:"text"
key:"inputID"
label:"Input Id"
order:1
required:true
value:ConfigItem [
displayName:"Input ID"
items:undefined
name:"inputID"
required:true
type:"text"]
]
]
thirst API 调用(表单构建后)会调用不同的 api 方法,参数相同的 moduleName,并返回这样的对象
Object
inputID:""
inputID:1
inputID:""
inputID:"default text"
enabled":true
其中每个 inputID 实际上是来自第二个 api 调用的标签 ID,而 enabled:true 应该针对第一个 api 调用的模块(当前存储在会话存储中)(如果数据不同,我将需要更新存储的项目)。
其中 api: items 被传递到动态表单组件中
<tab class="{{module.name}}-tab" *ngFor="let module of dpsModules; let i = index"
heading="{{module.displayName}}" (select)="beforeChange(module.name)">
<div class="dynamic-form" >
<dynamic-form [items]="items" >Loading...</dynamic-form>
</div>
</tab>
【问题讨论】:
-
item.value在您的toFormGroup函数中有什么作用?那应该是表单控件的值。不是吗?你能以某种方式将配置值合并/包含在第二个 API 调用中吗?你至少有一个键可以用来匹配表单控件的配置值吗? -
html中的每一项都是一个配置项数组。
-
最好将这类内容添加到问题中,而不是在 cmets 中,因为太难阅读了。另外,那里还有更多的工作空间。您可以使用
item.key(用作组数组中的索引)来查找从第三个 API 调用中获得的值吗?您要做的并不难,只要您可以将表单组数组与配置值链接在一起。 -
提出问题,抱歉
-
部分问题是这些表单在很多用例中需要是动态的,我无法在构建过程中添加其他值来填充默认数据。我需要一种将数据绑定到已经构建的表单的方法。我不确定我是否理解 如何 链接数组
标签: forms angular typescript dynamic api-design