如何使用/创建动态模板来使用Angular 2.0编译动态组件 - 来自字符串(JSON)

时间:2017-02-21 17:59:19

标签: json angular dynamic components

基于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"
    }
};

有关此通用组件创建方法/计时问题的任何建议都表示赞赏。

0 个答案:

没有答案