2016-07-19 126 views
3

我正在构建一个静态分析组件(来自角度应用程序)并将它们呈现在角度应用程序中的应用程序,类型为样式指南,但具有更多信息输入和组件等的其他方面。Angular 2 - 从字符串中动态加载组件

该应用程序使用webpack和分析一个组件,并返回到一个组件的“前端”(另一个角度的应用程序)信息,包括其源代码,我想渲染这个组件该应用程序。

动态组件加载程序要求您导入组件并引用它(Type),这是我没有的,因为此信息在运行时传递给应用程序。

我有点卡在如何渲染这个,angular2是否有某种机制来从字符串编译?使用某种代码生成,或者有更好的方法去实现它?

更清楚,我有:

{ 
"id": 0, 
"name": "carte-blanche-angular2", 
"kind": 0, 
"flags": {}, 
"children": [ 
    { 
     "id": 1, 
     "name": "\"component\"", 
     "kind": 1, 
     "kindString": "External module", 
     "flags": { 
      "isExported": true 
     }, 
     "originalName": "node_modules/carte-blanche-angular2/tmp/component.ts", 
     "children": [ 
      { 
       "id": 2, 
       "name": "NameComponent", 
       "kind": 128, 
       "kindString": "Class", 
       "flags": { 
        "isExported": true 
       }, 
       "decorators": [ 
        { 
         "name": "Component", 
         "type": { 
          "type": "reference", 
          "name": "Component" 
         }, 
         "arguments": { 
          "obj": "{\n selector: 'cb-name', // <name></name>\n styles: [`\n div{\n  color: red; \n  font-style:italic;\n }\n `],\n // The template for our name component\n template: `\n <div>name : {{name}}</div>\n `\n}" 
         } 
        } 
       ], 
       "children": [ 
        { 
         "id": 4, 
         "name": "constructor", 
         "kind": 512, 
         "kindString": "Constructor", 
         "flags": { 
          "isExported": true 
         }, 
         "signatures": [ 
          { 
           "id": 5, 
           "name": "new NameComponent", 
           "kind": 16384, 
           "kindString": "Constructor signature", 
           "flags": {}, 
           "type": { 
            "type": "reference", 
            "name": "NameComponent", 
            "id": 2 
           } 
          } 
         ] 
        }, 
        { 
         "id": 3, 
         "name": "name", 
         "kind": 1024, 
         "kindString": "Property", 
         "flags": { 
          "isExported": true 
         }, 
         "decorators": [ 
          { 
           "name": "Input", 
           "type": { 
            "type": "reference", 
            "name": "Input" 
           }, 
           "arguments": {} 
          } 
         ], 
         "type": { 
          "type": "instrinct", 
          "name": "string" 
         } 
        } 
       ], 
       "groups": [ 
        { 
         "title": "Constructors", 
         "kind": 512, 
         "children": [ 
          4 
         ] 
        }, 
        { 
         "title": "Properties", 
         "kind": 1024, 
         "children": [ 
          3 
         ] 
        } 
       ] 
      } 
     ], 
     "groups": [ 
      { 
       "title": "Classes", 
       "kind": 128, 
       "children": [ 
        2 
       ] 
      } 
     ] 
    } 
], 
"groups": [ 
    { 
     "title": "External modules", 
     "kind": 1, 
     "children": [ 
      1 
     ] 
    } 
] 
} 

哪家的产生typedoc:

"{ 
"id": 0, 
"name": "carte-blanche-angular2", 
"kind": 0, 
"flags": {}, 
"children": [ 
    { 
     "id": 1, 
     "name": "\"component\"", 
     "kind": 1, 
     "kindString": "External module", 
     "flags": { 
      "isExported": true 
     }, 
     "originalName": "node_modules/carte-blanche-angular2/tmp/component.ts", 
     "children": [ 
      { 
       "id": 2, 
       "name": "NameComponent", 
       "kind": 128, 
       "kindString": "Class", 
       "flags": { 
        "isExported": true 
       }, 
       "decorators": [ 
        { 
         "name": "Component", 
         "type": { 
          "type": "reference", 
          "name": "Component" 
         }, 
         "arguments": { 
          "obj": "{\n selector: 'cb-name', // <name></name>\n styles: [`\n div{\n  color: red; \n  font-style:italic;\n }\n `],\n // The template for our name component\n template: `\n <div>name : {{name}}</div>\n `\n}" 
         } 
        } 
       ], 
       "children": [ 
        { 
         "id": 4, 
         "name": "constructor", 
         "kind": 512, 
         "kindString": "Constructor", 
         "flags": { 
          "isExported": true 
         }, 
         "signatures": [ 
          { 
           "id": 5, 
           "name": "new NameComponent", 
           "kind": 16384, 
           "kindString": "Constructor signature", 
           "flags": {}, 
           "type": { 
            "type": "reference", 
            "name": "NameComponent", 
            "id": 2 
           } 
          } 
         ] 
        }, 
        { 
         "id": 3, 
         "name": "name", 
         "kind": 1024, 
         "kindString": "Property", 
         "flags": { 
          "isExported": true 
         }, 
         "decorators": [ 
          { 
           "name": "Input", 
           "type": { 
            "type": "reference", 
            "name": "Input" 
           }, 
           "arguments": {} 
          } 
         ], 
         "type": { 
          "type": "instrinct", 
          "name": "string" 
         } 
        } 
       ], 
       "groups": [ 
        { 
         "title": "Constructors", 
         "kind": 512, 
         "children": [ 
          4 
         ] 
        }, 
        { 
         "title": "Properties", 
         "kind": 1024, 
         "children": [ 
          3 
         ] 
        } 
       ] 
      } 
     ], 
     "groups": [ 
      { 
       "title": "Classes", 
       "kind": 128, 
       "children": [ 
        2 
       ] 
      } 
     ] 
    } 
], 
"groups": [ 
    { 
     "title": "External modules", 
     "kind": 1, 
     "children": [ 
      1 
     ] 
    } 
] 
}" 

这是我所提到的字符串。

感谢,

问候 若昂·加林

+0

它真的是一个动态组件加载的问题吗?或者它是动态路由的问题? –

+0

现在解决方案通过一个嵌入来自第一个应用程序(组件所属的应用程序)的bundle的iframe。但是,对于动态加载和东西的谈判,我认为也许角有一些魔术,可以采取一些字符串代表一个组件,只是呈现它; P eheh –

回答

1

你可以指数,这个组件串的服务,像这样:

export class ComponentIndexerService{ 
private clazzNames: Array<string>; 
classes: Array<new (...args:any[]) => any> 

public registerComponent(componentName : string, componentClass : new (...args[]) => any) 
    { 
    this.classNames.push(componentName); 
    this.classes.push(componentClass); 
    } 
} 

public get(componentName : string) { 
    let index : number = this.classNames.indexOf(componentName); 
    if(index > -1) { 
     return this.classes[index]; 
    } 
} 

然后注册:

componentIndexerService.register("someName", ComponentClass); 
componentIndexerService.register("someName2", ComponentClass2); 
componentIndexerService.register("someName3", ComponentClass3); 

最后使用:

constructor(dcl: DynamicComponentLoader, viewContainerRef: ViewContainerRef, componentIndexerService : ComponentIndexerService) { 
    let clazz : (...args:[]) => any = componentIndexerService.get("someName"); 
    dcl.loadNextToLocation(clazz, viewContainerRef); 
} 
+0

我会试试这个!感谢您的建议;) –

+0

欢迎您! 告诉我们,如果它的工作。 –

+0

我认为这个例子假定组件都是在类对象中定义的,而且我在字符串里面有一些信息,比如装饰器和类似的东西。所以不认为这会不幸的在我的情况下工作。我尝试了它,但我认为你发送“ClassItself”的地方它只是一个真正的类,所以你可以直接从它那里实例化。 –