I have developed an angular app which generates dynamic components. Those dynamic components are textbox and drowdown for now. I am getting what to use in a form from a service.
getPortalSettingsControls(): Observable<WizardItem[]> {
return this.http.get<WizardItem[]>('../../assets/mock_service/wizardData.json');
}
My wizardData.json is:
[
{
"id": 1,
"sortnumber": 1,
"headerText": "General Settings",
"wizardSettingItems":
[
{
"id": 1,
"sortNumber": 1,
"menuText": "AWS Settings",
"wizardComponentItems": [
{
"id": 1,
"sortNumber": 1,
"controlIdName": "agencyName",
"controlType": "Textbox",
"inputType": "text",
"labelText": "Agency Name"
},
{
"id": 2,
"sortNumber": 2,
"controlIdName": "agencyCode",
"controlType": "Textbox",
"inputType": "text",
"labelText": "Agency Code"
},
{
"id": 3,
"sortNumber": 3,
"controlIdName": "wsUserName",
"controlType": "Textbox",
"inputType": "text",
"labelText": "WS UserName"
},
{
"id": 4,
"sortNumber": 4,
"controlIdName": "wsPassword",
"controlType": "Textbox",
"inputType": "password",
"labelText": "WS Password"
},
{
"id": 5,
"sortNumber": 5,
"controlIdName": "customDomainUrl",
"controlType": "Textbox",
"inputType": "text",
"labelText": "Custom Domain URL"
},
{
"id": 6,
"sortNumber": 6,
"controlIdName": "wsap",
"controlType": "Textbox",
"inputType": "text",
"labelText": "WSAP"
},
{
"id": 7,
"sortNumber": 7,
"controlIdName": "wsOrganizationID",
"controlType": "Textbox",
"inputType": "text",
"labelText": "WS Organization ID"
},
{
"id": 8,
"sortNumber": 8,
"controlIdName": "wsOfficeID",
"controlType": "Textbox",
"inputType": "text",
"labelText": "WS Office ID"
},
{
"id": 9,
"sortNumber": 9,
"controlIdName": "wsUserName",
"controlType": "Textbox",
"inputType": "text",
"labelText": "WS Username"
},
{
"id": 10,
"sortNumber": 10,
"controlIdName": "wsPassword",
"controlType": "Textbox",
"inputType": "password",
"labelText": "WS Password"
},
{
"id": 11,
"sortNumber": 0,
"controlIdName": "market",
"controlType": "Dropdown",
"labelText": "Market",
"dropdownOption": [
{
"value": "Turkey",
"text": "Turkey"
},
{
"value": "France",
"text": "France"
},
{
"value": "Spain",
"text": "Spain"
}
]
}
]
}
]
}
]
As you can see there is only two types of components right now (Textbox and dropdown).
I have created one base model and two child models for these two components:
export class WizardComponentItem {
id: number;
sortNumber: number;
controlIdName: string;
controlType: string;
labelText: string;
value: string;
}
import { WizardComponentItem } from '../wizard-component-item.model';
export class WizardTextboxComponent extends WizardComponentItem {
inputType: string;
}
import { WizardComponentItem } from '../wizard-component-item.model';
export class WizardDropdownComponent extends WizardComponentItem {
dropdownOption: { value: any, text: string };
}
As you can see I am inheriting both of textbox and dropdown from base object model. In the service the return type is base object model (WizardComponentItem ).
Here is my dynamic component for textbox:
<div [formGroup]="form" class="form-group row">
<label [for]="controlIdName" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input [type]="type" class="form-control" [id]="controlIdName" [formControlName]="controlIdName">
</div>
</div>
For dropdown:
<div [formGroup]="form" class="form-group row">
<label [for]="controlIdName" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<select class="form-control" [id]="controlIdName" [formControlName]="controlIdName">
<option [value]="dropdownOption.value" *ngFor="let dropdownOption of dropdownOptions"></option>
</select>
</div>
</div>
And this is how I understand which dynamic component to attach:
attachFormComponents(wizardForm: FormGroup, wizardComponentItems: WizardComponentItem[], viewContainerRef: ViewContainerRef) {
for (let item of wizardComponentItems) {
let componentParams = Object.entries(item).map(([name, value]) => ({ name, value }));
componentParams.push({ name: "form", value: wizardForm });
switch (item.controlType) {
case "Textbox":
this.componentAttacher.attachComponent(WizardTextboxComponent, viewContainerRef, componentParams);
break;
case "Dropdown":
this.componentAttacher.attachComponent(WizardDropdownComponent, viewContainerRef, componentParams);
break;
default:
break;
}
}
}
Can you please advise me a design pattern or a way to map the json to a generic model and somehow understand it to extend to a textbox model or dropdown model? If you want further information please do not hesitate to ask for more.
Aucun commentaire:
Enregistrer un commentaire