12

I've tried many stackoverflow options like Load existing components dynamically Angular 2 Final Release.

What i want to do is get a html page with a ajax request and render/compile this template in my custom component.

I've figured out that angular2 has two deprecated components and that i have to use ComponentFactoryResolver.

In my old solution i could just set a '[innerHtml]' to render the HTML. Now i need a new solution.

Who can help me out?

page.component.ts

import { Component, ViewChild, ViewContainerRef, ComponentFactory, OnInit, ComponentFactoryResolver } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';


@Component({
    selector: "wd-page",
    templateUrl: "/app/page/page.component.html",
    providers: []
})
export class PageComponent implements OnInit {

    // we need the viewcontainer ref, so explicitly define that, or we'll get back
    // an element ref.
    @ViewChild('dynamicChild', { read: ViewContainerRef })
    private target: ViewContainerRef;

    private page = {
        Source: "<div><h2>Hello world</h2><one-of-my-components></one-of-my-components></div>"
    }


    constructor(
        private vcRef: ViewContainerRef,
        private resolver: ComponentFactoryResolver) { }


        ngOnInit() {
            //What code do i need here?
        }
}
<div #dynamicChild></div>

<!-- Old implementation!

    <div *ngIf="!showSource" [innerHTML]="page">
    </div>
-->
6
  • [innerHTML] never created components. stackoverflow.com/questions/40060498/… might do what you want. What do you think ComponentFactoryResolver is deprecated? Commented Oct 17, 2016 at 17:52
  • Hi Gunter, i've tried this solution but it only works for real angular components and not custom ones. I've edited the plunkr from you're post to recreate my problem. plnkr.co/edit/UACDPBRWNmvjVVsr0dWC Commented Oct 17, 2016 at 18:11
  • 2
    It works with custom components plnkr.co/edit/TAbupH4si62x10QZ7xuc?p=preview Commented Oct 17, 2016 at 18:34
  • I can't see in a blink of an eye what you did diffently compared to my snippet. Is it because you're component is inside a second module? Commented Oct 17, 2016 at 18:37
  • Aaah now i see what i did wrong. I did not import my 'custom components' into the dynamic module. Thanks for helping me out Yurzui! Commented Oct 17, 2016 at 18:41

2 Answers 2

9

Problem solved Thanks to Yurzui,

https://plnkr.co/edit/TAbupH4si62x10QZ7xuc?p=preview

The generic HTML outlete from a different post (Angular 2.1.0 create child component on the fly, dynamically) can be used to render templates with custom directives in them.

Don't forget to import a module with all the custom components that you want to render!

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
const cmpClass = class DynamicComponent {};
const decoratedCmp = Component(metadata)(cmpClass);

// Import the module with required components here
@NgModule({ imports: [CommonModule, RouterModule, SharedModule], declarations: [decoratedCmp] })
class DynamicHtmlModule { }

return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
   .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
    return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
  });
}
Sign up to request clarification or add additional context in comments.

Comments

1

I made tiny changes for using my own components (such as HomeComponent) at @Yurzui and @Linksonder 's solutions. https://plnkr.co/edit/27x0eg?p=preview

It's basically adding AppModule to DynamicHtmlModule as additional import inside of createComponentFactory().

@NgModule({ imports: [AppModule, CommonModule, RouterModule, SharedModule], declarations: [decoratedCmp] })
class DynamicHtmlModule { }

And exports our own components at AppModule

@NgModule({
  ...
  exports: [HomeComponent, AboutComponent],
  ...
})
export class AppModule { }

Comments

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.