2016-07-19 74 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」的地方它只是一個真正的類,所以你可以直接從它那裏實例化。 –