如果命名路由器出口有活动路线,则隐藏元素
Hide element if named router-outlet has active route
我们目前正在开发一个 Angular 13 应用程序,该应用程序分为几个独立的模块,由不同的团队维护,每个模块代表 UI 由其自身支持的不同应用程序微服务。
允许这些模块依赖于我们的“SharedModule”,但反之则不行。
现在,我们要实现一个“帮助中心”,它由一个浮动在右下角的问号按钮组成,如果单击它,则可以为当前加载的页面提供帮助。问题是,我们希望将每个模块的帮助中心页面的内容保留在该模块内,此外,某些模块不需要帮助中心页面。
我们当前的解决方案向我们的主布局添加了一个组件:
<router-outlet name="navbar"></router-outlet>
<router-outlet></router-outlet>
<app-help></app-help>
<router-outlet name="footer"></router-outlet>
app-help
组件有说浮动按钮,
<button mat-fab (click)="openHelpCenter()">
<mat-icon>help</mat-icon>
</button>
打开一个 Material 对话框,里面有一个名为 router-outlet
的对话框:
@Component({
selector: 'app-help',
templateUrl: './help.component.html',
styleUrls: ['./help.component.scss']
})
export class HelpComponent {
constructor(
private dialog: MatDialog,
) {
}
openHelpCenter() {
this.dialog.open(HelpDialogComponent, {
width: '300px'
})
}
}
@Component({
selector: 'app-help-dialog',
template: '<router-outlet name="help"></router-outlet>'
})
export class HelpDialogComponent {
constructor() {
}
}
在每个模块中,团队现在可以实现使用命名 router-outlet
:
的路由
...
{
path: '',
component: HelpComponent,
outlet: 'help'
}
...
它根据当前加载的 url.
在 Dialog 中“注入”模块 HelpComponent
这工作得很好,但是,我们有一个未解决的问题:
如果路由器出口为空,即如果您在不提供帮助的页面上,我们如何隐藏浮动按钮?
我认为最简单的解决方案(即用最少的模块内代码管理内容的解决方案)是在 HelpComponent
内监听 Router 事件,例如NavigationEnd
,然后找出“帮助”-router-outlet
是否有“活动”路由,并相应地设置可见性。 (类似于 RouterLinkActive
-指令)
但是,我无法找到如何从 Router
-Framework 中检索此信息。
当然,我也很感激关于如何以不同方式解决问题的想法。
您可以让服务保存一个布尔值,并让模块手动打开或关闭 init 上的帮助以满足它们的需要。我们在我们的应用程序中做了类似的事情,但也订阅了基于某些路线翻转的导航事件。
您还可以在路由中添加查询参数,例如 showhelp=true 或 false,并在主要组件中对其做出反应。
你也可以在主组件中有一个白名单,你可以在其中按住帮助按钮并在此处收听路由事件,然后使用映射来控制其上的 ngif。
很多选择,不确定哪个是最好的,我很好奇你最终选择了哪条路线
阅读 Angular 路由器源代码后,我偶然发现了 ChildrenOutletContexts
,它似乎是当前“活动”插座的地图。
我调整了我的组件以将其注入并在每次导航完成时检查它:
import {
ChildrenOutletContexts,
NavigationEnd,
Router
} from "@angular/router";
import {filter} from "rxjs";
import {map} from "rxjs/operators";
@Component({
selector: 'app-help',
templateUrl: './help.component.html',
styleUrls: ['./help.component.scss']
})
export class HelpComponent {
helpOutletActive$ = this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.contexts.getContext('help') !== null)
)
constructor(
private dialog: MatDialog,
private router: Router,
private contexts: ChildrenOutletContexts
) {
}
openHelpCenter() {
this.dialog.open(HelpDialogComponent, {
width: '300px'
})
}
}
根据我的测试,这似乎产生了预期的结果
我们目前正在开发一个 Angular 13 应用程序,该应用程序分为几个独立的模块,由不同的团队维护,每个模块代表 UI 由其自身支持的不同应用程序微服务。 允许这些模块依赖于我们的“SharedModule”,但反之则不行。
现在,我们要实现一个“帮助中心”,它由一个浮动在右下角的问号按钮组成,如果单击它,则可以为当前加载的页面提供帮助。问题是,我们希望将每个模块的帮助中心页面的内容保留在该模块内,此外,某些模块不需要帮助中心页面。
我们当前的解决方案向我们的主布局添加了一个组件:
<router-outlet name="navbar"></router-outlet>
<router-outlet></router-outlet>
<app-help></app-help>
<router-outlet name="footer"></router-outlet>
app-help
组件有说浮动按钮,
<button mat-fab (click)="openHelpCenter()">
<mat-icon>help</mat-icon>
</button>
打开一个 Material 对话框,里面有一个名为 router-outlet
的对话框:
@Component({
selector: 'app-help',
templateUrl: './help.component.html',
styleUrls: ['./help.component.scss']
})
export class HelpComponent {
constructor(
private dialog: MatDialog,
) {
}
openHelpCenter() {
this.dialog.open(HelpDialogComponent, {
width: '300px'
})
}
}
@Component({
selector: 'app-help-dialog',
template: '<router-outlet name="help"></router-outlet>'
})
export class HelpDialogComponent {
constructor() {
}
}
在每个模块中,团队现在可以实现使用命名 router-outlet
:
...
{
path: '',
component: HelpComponent,
outlet: 'help'
}
...
它根据当前加载的 url.
在 Dialog 中“注入”模块 HelpComponent这工作得很好,但是,我们有一个未解决的问题:
如果路由器出口为空,即如果您在不提供帮助的页面上,我们如何隐藏浮动按钮?
我认为最简单的解决方案(即用最少的模块内代码管理内容的解决方案)是在 HelpComponent
内监听 Router 事件,例如NavigationEnd
,然后找出“帮助”-router-outlet
是否有“活动”路由,并相应地设置可见性。 (类似于 RouterLinkActive
-指令)
但是,我无法找到如何从 Router
-Framework 中检索此信息。
当然,我也很感激关于如何以不同方式解决问题的想法。
您可以让服务保存一个布尔值,并让模块手动打开或关闭 init 上的帮助以满足它们的需要。我们在我们的应用程序中做了类似的事情,但也订阅了基于某些路线翻转的导航事件。
您还可以在路由中添加查询参数,例如 showhelp=true 或 false,并在主要组件中对其做出反应。
你也可以在主组件中有一个白名单,你可以在其中按住帮助按钮并在此处收听路由事件,然后使用映射来控制其上的 ngif。
很多选择,不确定哪个是最好的,我很好奇你最终选择了哪条路线
阅读 Angular 路由器源代码后,我偶然发现了 ChildrenOutletContexts
,它似乎是当前“活动”插座的地图。
我调整了我的组件以将其注入并在每次导航完成时检查它:
import {
ChildrenOutletContexts,
NavigationEnd,
Router
} from "@angular/router";
import {filter} from "rxjs";
import {map} from "rxjs/operators";
@Component({
selector: 'app-help',
templateUrl: './help.component.html',
styleUrls: ['./help.component.scss']
})
export class HelpComponent {
helpOutletActive$ = this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.contexts.getContext('help') !== null)
)
constructor(
private dialog: MatDialog,
private router: Router,
private contexts: ChildrenOutletContexts
) {
}
openHelpCenter() {
this.dialog.open(HelpDialogComponent, {
width: '300px'
})
}
}
根据我的测试,这似乎产生了预期的结果