基于How can I use/create dynamic template to compile dynamic Component with Angular 2.0我目前在从远程服务器检索的json字符串中创建组件模型的动态属性时遇到时间问题。
在新实体中正确动态创建属性 - 稍后将其分配给空实体,但托管组件已绑定到空实体,并且在初始化时不知道有关动态创建的属性的任何信息。当服务器的json结果异步到达并稍后到达时,似乎已经完成了托管组件的创建。
因此,页面将应用没有任何属性数据的空组件列表。显示的组件数等于动态添加的属性。但动态数据绑定显然对附加到属性的数据一无所知。
前面提到的原始方法循环实体对象的一组硬连线属性,以使用特定属性名为每个属性组装完整模板。
定义硬连线实体对象:
entity = {
code: "ABC123",
description: "A description of this Entity"
};
组装循环实体属性的动态模板字符串:
import {Injectable} from "@angular/core";
@Injectable()
export class DynamicTemplateBuilder {
public prepareTemplate(entity: any, useTextarea: boolean){
let properties = Object.keys(entity);
let template = "<form >";
let editorName = useTextarea
? "text-editor"
: "string-editor";
properties.forEach((propertyName) =>{
template += `
<${editorName}
[propertyName]="'${propertyName}'"
[entity]="entity"
></${editorName}>`;
});
return template + "</form>";
}
}
我的方法试图处理完整的可配置方法:
Json字符串
{
"code": {
"id": "ADRESSE-UPDATE-001",
"componentType": "text-editor",
"rows": 5,
"cols": 25,
"value": "Hello !"
},
"description": {
"id": "ADRESSE-UPDATE-002",
"componentType": "string-editor",
"rows": 1,
"cols": 50,
"value": "Please enter some data"
},
"Street": {
"id": "ADRESSE-UPDATE-003",
"componentType": "text-editor",
"rows": 10,
"cols": 100,
"value": "Mainstreet"
},
"City": {
"id": "ADRESSE-UPDATE-004",
"componentType": "text-editor",
"rows": 3,
"cols": 5,
"value": "Hamburg"
}
}
基本上,Json检索和属性创建组织为:
import { Injectable } from '@angular/core';
import {Http, Response} from "@angular/http";
import { Headers, RequestOptions } from '@angular/http';
import {IValue, IEntityClassAdvanced, Member} from './dynamic-config-interfaces';
var jsonX;
@Injectable()
export class DynamicConfigBuilder{
constructor(private http: Http)
{
}
getEntity(callback):any{
this.callConfigApi(callback);
}
callConfigApi(callback:any) {
jsonX = null;
var content = { "Action": "REQUEST-FOR-CONFIG", "Type": 'CONFIG', "Raw":""};
var jsonText = JSON.stringify(content);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post('http://localhost:9123/tasks/config',jsonText, options)
.map((res: Response) => res.json())
.subscribe((message: string) => {
jsonX = JSON.parse(message);
console.log(JSON.stringify(jsonX));
//alert("loaded from server: " + JSON.stringify(jsonX));
var entity: IEntityClassAdvanced = {};
Object.keys(jsonX).forEach(function (key) {
entity[key] = { propertyValue: null };
var val = entity[key];
val.propertyValue = new Member().deserialize(jsonX[key]);
});
callback(entity);
});
}
}
必要的接口和类型位于单独的文件中:
import { Injectable} from '@angular/core';
//--- typed nested object from json:
export interface Serializable<T> {
deserialize(input: Object): T;
}
@Injectable()
export class Member implements Serializable<Member> {
id: string;
componentType: string;
rows: number;
cols:number;
value:string;
deserialize(input) {
this.id = input.id;
this.componentType = input.componentType;
this.rows = input.rows;
this.cols = input.cols;
this.value = input.value;
return this;
}
}
//--- dynamic object builder elements
export interface IValue {
propertyValue: Member
}
export interface IEntityClassAdvanced {
[name: string]: IValue;
}
//--- end dynamic object builder
在回调方法中,会发生延迟分配:
private entityCallback(entityItem:any)
{
//alert("--->" + JSON.stringify(entityItem));
this.entity = entityItem;
this.refreshContent();
}
模板创建的风格略有不同:
public prepareTemplate(entity:any, useTextarea: boolean){
let properties = Object.keys(entity);
let template = "<form >";
let editorName = useTextarea
? "otago-text-editor"
: "string-editor";
properties.forEach((propertyName) =>{
// alert(propertyName);
let targetComponent = entity[propertyName]["propertyValue"]["componentType"];
template += `
<${targetComponent}
[propertyName]="'${propertyName}'"
[entity]="entity"
></${targetComponent}>`;
});
return template + "</form>";
}
使用在编译时已存在的嵌套内联对象尝试硬连线方法时,绑定工作正常:
var json = {
code: {
id: "ADRESSE-UPDATE-001",
componentType: "text-editor",
rows:5,
cols:25,
value:"Hello !"
},
description: {
id: "ADRESSE-UPDATE-002",
componentType: "string-editor",
rows:1,
cols:50,
value:"Please enter some data"
},
firstMember: {
id: "ADRESSE-UPDATE-003",
componentType: "text-editor",
rows:10,
cols:100,
value:"Mainstreet"
},
secondMember: {
id: "ADRESSE-UPDATE-004",
componentType: "text-editor",
rows:3,
cols:5,
value:"Hamburg"
}
};
有关此通用组件创建方法/计时问题的任何建议都表示赞赏。