使用 Angular2 中 api 的默认数据填充动态表单
Populate dynamic forms with default data from api in Angular2
我已经使用 angular2 几个星期了,我正在尝试为系统设置页面创建动态表单。
目标:拥有 api return 任意数量的表单,在选项卡内构建表单,表单可以具有任何 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 调用 return 那个表单的配置数据;我需要将这些数据绑定到每个特定的表单。
我无法创建典型的 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>
其中项目是 api 中的 return。它的结构如下:
第一次调用是这样的
ModuleList [{"name":"moduleName","displayName":"Module Name","enabled":true}]
一些其他不相关的代码运行,然后使用 maduleName 参数对 return 布局进行 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 调用(在构建表单后)将调用具有相同参数 moduleName 的不同 api 方法,并且 return 一个像这样的对象
Object
inputID:""
inputID:1
inputID:""
inputID:"default text"
enabled":true
其中每个 inputID 实际上是来自第二个 api 调用的标签 ID,并且 enabled:true 应该以来自第一个 api 的模块(当前存储在会话存储中)为目标调用(如果数据不同,我将需要更新存储的项目)。
其中 api: 项目被传递到动态表单组件
<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>
我从您的问题中收集到的信息是否正确,您从 third API 中获得的数据应该具有您想要应用于表格的值根据您在 second API 通话中获得的信息构建的组。
如果这是正确的,那么您需要遍历第三次 API 调用的结果并将值应用到表单组(应该在您开始此操作时构建)。
我假设 JavaScript/Typescript 中的 looping/iterating 是您熟悉的内容。
我还假设来自第三次 API 调用的数据有一个字段或值,它将允许您识别需要为其分配值的表单控件。对于此演示,我将使用 item.key
作为 linking 标记。
这是您需要尝试的伪代码:
for each item.key
this.form.controls[item.key].value = item.value;
this.form
是您组件中已有的内容。您使用其中的 controls
集合以及索引值(在本例中为 item.key
)来读取或分配控件的 value
。
如果您没有可以在第三次 API 调用中提供表单组和数据之间的 link 的东西,那么绑定它们即使不是不可能,也是很困难的。如果您拥有的不仅仅是键,例如键和描述,您可以通过一些简单的连接来使用它。
希望对您有所帮助!
我已经使用 angular2 几个星期了,我正在尝试为系统设置页面创建动态表单。 目标:拥有 api return 任意数量的表单,在选项卡内构建表单,表单可以具有任何 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 调用 return 那个表单的配置数据;我需要将这些数据绑定到每个特定的表单。
我无法创建典型的 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>
其中项目是 api 中的 return。它的结构如下: 第一次调用是这样的
ModuleList [{"name":"moduleName","displayName":"Module Name","enabled":true}]
一些其他不相关的代码运行,然后使用 maduleName 参数对 return 布局进行 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 调用(在构建表单后)将调用具有相同参数 moduleName 的不同 api 方法,并且 return 一个像这样的对象
Object
inputID:""
inputID:1
inputID:""
inputID:"default text"
enabled":true
其中每个 inputID 实际上是来自第二个 api 调用的标签 ID,并且 enabled:true 应该以来自第一个 api 的模块(当前存储在会话存储中)为目标调用(如果数据不同,我将需要更新存储的项目)。
其中 api: 项目被传递到动态表单组件
<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>
我从您的问题中收集到的信息是否正确,您从 third API 中获得的数据应该具有您想要应用于表格的值根据您在 second API 通话中获得的信息构建的组。
如果这是正确的,那么您需要遍历第三次 API 调用的结果并将值应用到表单组(应该在您开始此操作时构建)。
我假设 JavaScript/Typescript 中的 looping/iterating 是您熟悉的内容。
我还假设来自第三次 API 调用的数据有一个字段或值,它将允许您识别需要为其分配值的表单控件。对于此演示,我将使用 item.key
作为 linking 标记。
这是您需要尝试的伪代码:
for each item.key
this.form.controls[item.key].value = item.value;
this.form
是您组件中已有的内容。您使用其中的 controls
集合以及索引值(在本例中为 item.key
)来读取或分配控件的 value
。
如果您没有可以在第三次 API 调用中提供表单组和数据之间的 link 的东西,那么绑定它们即使不是不可能,也是很困难的。如果您拥有的不仅仅是键,例如键和描述,您可以通过一些简单的连接来使用它。
希望对您有所帮助!