我正在尝试为Angular 2应用程序找到一个好的结构,它有类似于相互依赖的组件。
以下是问题的基本概念: 应该有侧导航菜单组件和应该包含路由器插座的内容区域。对于某些路线,侧面组件应包含用于导航的附加组件(例如,用于快速访问的项目列表,其中主要内容区域为“详细视图”)。
Top level template structure:
<sidenav>
<featureA-nav-fragment></featureA-nav-fragment>
</sidenav>
<router-outlet>
<!-- featureA component -->
</router-outlet>
菜单应该是与任何其他组件或功能区域无关的组件,并且不应该知道其他导航组件,但它应该包装此组件。
实现的一种方法是仅定义顶级组件,并且在路由定义的每个屏幕中提供HTML模板中的侧边菜单。在我看来,这是糟糕的设计原因,HTML代码的部分内容是重复的。
另一种选择是在菜单组件中的活动路径上创建一个开关,并在那里包含正确的导航片段,但这会将路径(屏幕)的逻辑分散到几个组件中,这似乎是一个更糟糕的设计。我
使用命名的路由器插座导航片段不是正确的方法,因为组件不是彼此独立显示,而是始终在一起。手动修改路线(清除导航片段部分)会破坏设计。
我还没有在角度文档中找到这样一个用例的好设计。我在这里错过了什么吗?
答案 0 :(得分:0)
我终于找到了自己的解决方案。
如果遇到某些组件应将其模板内容的一部分注入另一个组件的问题,您可能希望将结构指令与自定义路由器服务一起使用。
这种模式的一般思想是在主视图组件的模板中使用特定的结构指令(上面的featureA组件)。
<div *embeddedIntoNav>some navigation related content</div>
<div>
Feature A view
<div>
该指令是通过将模板引用转发到自定义路由器服务来实现的。
@Directive({
selector: '[embeddedIntoNav]'
})
export class EmbeddedIntoNavDirective {
constructor(
private customRouter: CustomRouter,
private templateRef: TemplateRef<any>
) { }
ngOnInit() {
this.customRouter.navContent$.next(this.templateRef);
}
ngOnDestroy() {
this.customRouter.navContent$.next(null);
}
}
使用此结构指令进行调查的部分不会附加到功能A的子项中,而只会附加到路由器上。路由器实现是每个嵌入式视图插座的一组BehaviorObservable。
另一个指令用于定义嵌入视图的出口:
@Directive({
selector: 'nav-container'
})
export class NavContainerDirective implements OnInit {
constructor(
private viewContainer: ViewContainerRef,
private customRouter: CustomRouter
) {
}
ngOnInit() {
this.customRouter.navContent$.subscribe((template) => {
this.viewContainer.clear();
if (template) {
this.viewContainer.createEmbeddedView(template);
}
});
}
}
使用此模式,您可以构建路由器,只需触摸单个文件即可注入多个视图,并将逻辑保存在一个位置。