使用 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 的东西,那么绑定它们即使不是不可能,也是很困难的。如果您拥有的不仅仅是键,例如键和描述,您可以通过一些简单的连接来使用它。

希望对您有所帮助!