3

I am building an app that statically analyses components (from an angular app) and renders them in a angular app, sort of a style guide but with more information where it has information on inputs and other aspects of the component etc..

The app uses webpack and analyzes a component and returns to a "frontend" (another angular app) information about a component including its source code and I want to render this component in that app.

Dynamic component loader requires that you have imported the component and have a reference to it (Type), which I don't have as this information is passed to the app at runtime.

I am a bit stuck on how to render this, does angular2 have some sort of mechanism to compile from a string? using some sort of code generation, or maybe there is a better way to go at it?

To be more clear I have :

{
"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
        ]
    }
]
}

Which is the generated typedoc of :

"{
"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
        ]
    }
]
}"

Which is the string I mentioned.

Thanks,

Best regards Joao Garin

2
  • is it really a question of dynamic component loading? or is it a question of dynamic routing? Commented Jul 19, 2016 at 19:55
  • Right now the solution passes around an iframe embeding the bundle from that first app (the one where the component belongs to). But yeah with the talks of dynamic loading and stuff I thought maybe angular has some magic that can take some string representing a component and just render it;P eheh Commented Jul 19, 2016 at 20:01

1 Answer 1

1

You could index this component as string in a service, something like this:

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];
    }
}

Then register:

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

And Finally use:

constructor(dcl: DynamicComponentLoader, viewContainerRef: ViewContainerRef, componentIndexerService : ComponentIndexerService) {
    let clazz : (...args:[]) => any = componentIndexerService.get("someName");
    dcl.loadNextToLocation(clazz, viewContainerRef);
}
Sign up to request clarification or add additional context in comments.

8 Comments

I think the example assumes the component is all defined in the class object and I do have some info inside the string like decorators and things like that. So dont think that would work in my case unfortunately. I tried it but I think where you send "ClassItself" it assuems is just a actuall class so you can instanciate it direclty from that.
The class Itself is just the component class registered to be instantiated by Angular. I will change the name for ComponentClass, I think it`s better.
But the thing is I dont have the class right..I have the string representation of the class, as a string. not as an actual class..
Also I have decorators like the @component decorators that I would need to render the actual template of it.
Essencially what I have is a representation of the source file where the component was created (so a string of everything in that file) and I have a typedoc generated object of that component as well. the typedoc generated object is quite complex but I guess it could be used to build a Component and use dyanamic loader to load it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.