Angular 4 ngComponentOutlet loads dynamic components, but route content is not being rendered

Viewed 4581

I'm trying to load different 'parent' components and inject route content into these different parent components by targeting ng-content in each parent component. Essentially, each parent component handles the navigation and other boilerplate stuff based on device widths (small/mobile, medium/tablet, and large/desktop).

The content generated for each route in my application needs to get transcluded (injected) into the parent components. The content for each route targets specific injection points using ng-content.

I'm able to swap out the parent components using <ng-container *ngComponentOutlet="ResponsiveComponent;"></ng-container>. The problem is my route-generated content is not getting injected into the targeted ng-content locations in each parent component.

Here's the code for swapping out parent components. AppPageComponent extends ResponsiveComponent which monitors device width based on media queries.

@Component({
    selector: 'app-page',
    template: `
        <ng-container *ngComponentOutlet="ResponsivePageComponent;"></ng-container>     
    `,  
    styleUrls: [ './page.component.scss'],
    providers: []
})
export class AppPageComponent extends ResponsiveComponent implements OnInit, OnDestroy
{
    ResponsivePageComponent;

    constructor(
        injector: Injector,
        zone: NgZone)
    {
        super(zone);    
    }

    ngOnInit()
    {       
        this.IsSmallEnvironmentStream
            .subscribe
            (
                (isSmall: boolean) =>
                { 
                    if (isSmall)
                    { 
                        this.ResponsivePageComponent= AppPageSmallComponent;
                    }                   
                },
                (err) => { },
                () => {}
            );

        this.IsMediumEnvironmentStream
            .subscribe
            (
                (isMedium: boolean) =>
                { 
                    if (isMedium)
                    { 
                        this.ResponsivePageComponent = AppPageMediumComponent;
                    }                   
                },
                (err) => { },
                () => {}
            );

        this.IsLargeEnvironmentStream
            .subscribe
            (
                (isLarge: boolean) =>
                { 
                    if (isLarge)
                    { 
                        this.ResponsivePageComponent = AppPageLargeComponent;
                    }                   
                },
                (err) => { },
                () => {}
            );      
    }
}

Angular's documentation for NgComponentOutlet shows you can target optional list of projectable nodes to insert into the content (ng-content) placeholders. I followed the examples from Angular's documentation and was able to inject text nodes into the different ng-content placeholders in my parent components and it works for my small/medium/large parent components.

How do I get the content from my routes to inject into these different placeholders? It seems like I'm really close to getting this to work. I can inject in essence static content into the palceholders, but I can not figure out how to inject the content generated by routes into the placeholders.

UPDATE - 07/25/2017

I created this plunker demonstrating this scenario (https://plnkr.co/edit/hOwRX1Ml6gX0S8em6nd5?p=preview).

In the plunker, page-wrapper component uses ngComponentOutlet to load small/medium/large component depending upon device width. page-wrapper component is injecting static content into the placeholders in each small/medium/large component instead of injecting route content from page 1.

My objective is to have a page wrapper component to handle responsive needs like different navigation elements for small/medium/large responsive designs.

So, how can 'static' content be injected into dynamically loaded component's ng-content placeholders yet route generated content is not being injected into ng-content placeholders?

Thanks for your help.

2 Answers
Related