使用Angular2中的api的默认数据填充动态表单

时间:2017-03-16 19:16:46

标签: forms angular typescript dynamic api-design

我已经使用angular2几周了,我正在尝试为系统设置页面创建动态表单。 目标:让api返回任意数量的表单,在选项卡内部构建表单,表单可以包含任何 type 字段,并使用默认或以前保存的数据填充这些表单然后进行修改和保存。 / p>

什么有效:使用任意数量的输入字段创建任意数量的表单。 我需要帮助填充数据表单。 这是从api调用生成的项目。需要填充这些felids的数据我需要单独的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>

其中item是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"]
        ]
    ]

第一个API调用(在构建表单之后)将使用相同的moduleName参数调用另一个api方法,并返回一个这样的对象

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>

1 个答案:

答案 0 :(得分:0)

我从您的问题收集的内容是否正确,您从第三个​​ API获取的数据应该具有您要应用于您根据所获信息构建的表单组的值在第二次 API调用中。

如果这是正确的,那么您需要遍历第三个API调用的结果并将值应用于表单组(应该在您开始时构建)。

我假设在JavaScript / Typescript中循环/迭代是你熟悉的东西。

我还将假设来自第三个API调用的数据具有字段或值,以便您可以识别需要将其值分配给的表单控件。对于此演示,我将使用item.key作为链接令牌。

以下是您需要尝试的伪代码:

for each item.key 
  this.form.controls[item.key].value = item.value;

this.form是您组件中已有的内容。您可以在其中使用controls集合以及索引值(在本例中为item.key)来读取或分配控件的value

如果您没有能够在第三次API调用中提供表单组和数据之间的链接,那么绑定它们可能会很困难,如果不是不可能的话。如果你拥有的不仅仅是一个键,比如一个键和描述,你可以使用一些简单的连接。

我希望这会帮助你!