Angular 4 ngComponentOutlet加载动态组件,但不呈现路由内容

时间:2017-07-23 05:16:54

标签: angular angular2-ngcontent router-outlet ng-component-outlet

我试图加载不同的父母'组件并通过在每个父组件中定位ng-content将路由内容注入到这些不同的父组件中。基本上,每个父组件都会根据设备宽度(小型/移动,中型/平板电脑和大型/台式机)处理导航和其他样板材料。

我的应用程序中为每个路由生成的内容需要被转换(注入)到父组件中。每条路线的内容使用ng-content确定特定注入点。

我可以使用<ng-container *ngComponentOutlet="ResponsiveComponent;"></ng-container>换出父组件。问题是我的路由生成内容没有被注入到每个父组件中的目标ng-content位置。

这是用于交换父组件的代码。 AppPageComponent扩展ResponsiveComponent,根据媒体查询监控设备宽度。

@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的NgComponentOutlet文档显示,您可以将可插入节点的可选列表作为目标插入内容(ng-content)占位符。我按照Angular的文档中的示例进行操作,并且能够将文本节点注入到我的父组件中的不同ng-content占位符中,并且它适用于我的小/中/大父组件。

如何从我的路线中获取内容以注入这些不同的占位符?看起来我真的很接近这个工作。我可以将静态内容注入到掌上电脑中,但我无法弄清楚如何将路由生成的内容注入占位符。

更新 - 07/25/2017

我创建了这个plunker demonstrating this scenariohttps://plnkr.co/edit/hOwRX1Ml6gX0S8em6nd5?p=preview)。

在plunker中,page-wrapper组件使用ngComponentOutlet根据设备宽度加载小/中/大组件。 page-wrapper组件将静态内容注入每个小/中/大组件的占位符,而不是从第1页注入路由内容。

我的目标是拥有一个页面包装器组件来处理响应式需求,例如用于小型/中型/大型响应式设计的不同导航元素。

那么,怎样才能静止&#39;内容被注入到动态加载的组件ng-content占位符中,但路由生成的内容没有被注入ng-content占位符?

感谢您的帮助。

2 个答案:

答案 0 :(得分:8)

1)您可以在PageWrapperComponent中定义ng-content个位置并将它们转换为动态组件

页-wrapper.component.html

<ng-container *ngComponentOutlet="ResponsiveComponent; 
                                content: [[el1],[el2]]"></ng-container>
<div #el1>
  <ng-content></ng-content>
</div>
<div #el2>
  <ng-content select="[named-injection-point]"></ng-content>
</div>

<强> Plunker Example

2)您还可以在父组件中使用模板引用变量(或自定义指令),在@ContentChild中使用PageWrapperComponent来获取转换部分。

页-one.component.html

<page-wrapper>
    <section #mainPoint>
        <h2>Page One</h2>
    </section>
    <section #namedPoint>
        <h3>Page One Content:</h3>
        <p>Lorem ipsum dolor.</p>
    </section>
</page-wrapper>

页-wrapper.component.ts

@ContentChild('mainPoint') mainPoint;
@ContentChild('namedPoint') namedPoint;

页-wrapper.component.html

<ng-container *ngComponentOutlet="ResponsiveComponent; 
        content: [[mainPoint.nativeElement],[namedPoint.nativeElement]]"></ng-container>

<强> Plunker Example

答案 1 :(得分:0)

这是你期待的吗?我只测试过中型组件BTW ......

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

我认为这是因为您尝试在组件中使用ng-content,而该组件不是从具有您要注入的内容的组件直接调用的。我所做的就是在PageWrapperComponent上添加一个ng-content,使用它自己的选择器,然后将其传递给下一个组件,并使用一个期望的选择器。

... PageWrapperComponent

<ng-content select="[injected-content]" named-injection-point></ng-content>

然后在PageOneComponent中使用了Wrapper期待的新选择器

<section injected-content>
  <h3>Page One Content:</h3>
  <p>Lorem ipsum ...</p>
</section>       

当我点击第1页链接时,我现在可以在Jimmy和Fred下面看到Page One Content。