0

For example, I have a list of options in one Component, where clicking on one renders a Component dynamically based on the user's selection. This is how I image it would be done:

List Component

import { Component } from '@angular/core';
@Component({
    selector: 'list-component',
    templateUrl: `
        <ul>
            <li *ngFor="let item from list" (click)="onClick(item)">{{item.name}}</li>
        </ul>
    `
})
export class ListComponent {

    list = [
        {name: 'Component1'},
        {name: 'Component2'},
        {name: 'Component3'}
    ]

    constructor(private _listService: ListService) {

    }

    onClick(item) {
        this._listService.renderComponent(item);
    }
}

Render Component

import { Component, ViewContainerRef } from '@angular/core';

@Component({
    selector: 'render-component',
    templateUrl: `
        <div #dynamicComponent></div>
    `
})
export class RenderComponent {

    @ViewChild('dynamicComponent', { read: ViewContainerRef })
    private dynamicComponent: any;

    constructor(
        private _listService: ListService,
        private resolver: ComponentFactoryResolver
    ) {

        this._listService.onRenderComponent.subscribe(item => {
            let componentReference;

            //TODO: Get Component by reference ???

            let componentFactory = this.resolver.resolveComponentFactory(componentReference);
            this.dynamicComponent.createComponent(componentFactory);

        })
    }
}

I've left the details about ListService but it is essentially a service that allows the two components to communicate.

I would prefer not to have references to components inside ListComponent like so:

import {Component1, Component2, Component3} from './otherComponents';

...

list = [
    {name: 'Component1', component: Component1},
    {name: 'Component2', component: Component2},
    {name: 'Component3', component: Component3}
]

...

this._listService.onRenderComponent.subscribe(item => {
    let componentReference = item.component;

    let componentFactory = this.resolver.resolveComponentFactory(componentReference);
    this.dynamicComponent.createComponent(componentFactory);

})

and let the ListService handle it.

So essentially, does angular provide methods for retrieving a Component based on some references such as selector, componentId or something along those line?

1

1 Answer 1

1

If you using Angular 2.0 final (which I don't think you are), you can actually resolve the component via a selector.

 const compFactory = this.factory.componentFactories.find(x => x.selector === 'my-component-selector');
    const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
    const cmpRef = this.vcRef.createComponent(compFactory, this.vcRef.length, injector, []);

I have a minimalist example of dynamic component creation here

Sign up to request clarification or add additional context in comments.

2 Comments

Seems he doesn't use Compiler He prefers to use ComponentFactoryResolver together with entryComponents or ANALYZE_FOR_ENTRY_COMPONENTS provider for dynamic component creation.
Fair enough. Has that been deprecated though? I can't tell.

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.