Angular 4 ngComponentOutlet 加载动态组件,但路由内容未被渲染
Angular 4 ngComponentOutlet loads dynamic components, but route content is not being rendered
我正在尝试加载不同的 'parent' 组件,并通过在每个父组件中定位 ng-content
将路由内容注入到这些不同的父组件中。本质上,每个父组件都根据设备宽度(small/mobile、medium/tablet 和 large/desktop)处理导航和其他样板内容。
我的应用程序中为每个路由生成的内容需要嵌入(注入)到父组件中。每个路由的内容使用 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
占位符,它适用于我的 small/medium/large 父组件。
如何从我的路由中获取内容以注入到这些不同的占位符中?看来我真的很接近让它发挥作用了。我本质上可以将静态内容注入占位符,但我不知道如何将路由生成的内容注入占位符。
更新 - 2017 年 7 月 25 日
我创建了这个plunker demonstrating this scenario (https://plnkr.co/edit/hOwRX1Ml6gX0S8em6nd5?p=preview)。
在 plunker 中,page-wrapper
组件使用 ngComponentOutlet 根据设备宽度加载 small/medium/large 组件。 page-wrapper 组件将静态内容注入到每个 small/medium/large 组件的占位符中,而不是从第 1 页注入路由内容。
我的 objective 是要有一个页面包装器组件来处理响应需求,例如 small/medium/large 响应式设计的不同导航元素。
那么,如何将 'static' 内容注入到动态加载组件的 ng-content
占位符中,而路由生成的内容却没有注入到 ng-content
占位符中?
感谢您的帮助。
这是您期待的吗?我只测试了中型组件顺便说一句...
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 下面看到第一页的内容 link。
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>
2) 您还可以在父组件中使用模板引用变量(或自定义指令)并在 PageWrapperComponent
中使用 @ContentChild
来获取包含部分。
页-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>
我正在尝试加载不同的 'parent' 组件,并通过在每个父组件中定位 ng-content
将路由内容注入到这些不同的父组件中。本质上,每个父组件都根据设备宽度(small/mobile、medium/tablet 和 large/desktop)处理导航和其他样板内容。
我的应用程序中为每个路由生成的内容需要嵌入(注入)到父组件中。每个路由的内容使用 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
占位符,它适用于我的 small/medium/large 父组件。
如何从我的路由中获取内容以注入到这些不同的占位符中?看来我真的很接近让它发挥作用了。我本质上可以将静态内容注入占位符,但我不知道如何将路由生成的内容注入占位符。
更新 - 2017 年 7 月 25 日
我创建了这个plunker demonstrating this scenario (https://plnkr.co/edit/hOwRX1Ml6gX0S8em6nd5?p=preview)。
在 plunker 中,page-wrapper
组件使用 ngComponentOutlet 根据设备宽度加载 small/medium/large 组件。 page-wrapper 组件将静态内容注入到每个 small/medium/large 组件的占位符中,而不是从第 1 页注入路由内容。
我的 objective 是要有一个页面包装器组件来处理响应需求,例如 small/medium/large 响应式设计的不同导航元素。
那么,如何将 'static' 内容注入到动态加载组件的 ng-content
占位符中,而路由生成的内容却没有注入到 ng-content
占位符中?
感谢您的帮助。
这是您期待的吗?我只测试了中型组件顺便说一句...
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 下面看到第一页的内容 link。
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>
2) 您还可以在父组件中使用模板引用变量(或自定义指令)并在 PageWrapperComponent
中使用 @ContentChild
来获取包含部分。
页-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>