Angular 2 根据当前路由器状态更改 sidenav 内容
Angular 2 change sidenav content depending on the current router state
我正在 Angular 开发单页应用程序 2. 我正在使用 angular material mat-sidenav 和 mat-toolbar。工具栏有 sidenav 切换按钮,用于打开 'Clients' 部分和 'Reports' 部分的按钮。这种结构在整个项目中很常见。
所以应用看起来像这样:
我必须根据路由器的当前状态更改 sidenav(和主字段)中的内容。因此,如果打开 'Clients' 部分,sidenav 应该会显示一些与客户端相关的小节。同样,对于 'Reports' 部分,只有与报告相关的小节应该可用。我该怎么做?
我通过检查 URL 路径是否包含某些指定部分来做到这一点。例如,如果你想为客户提供可见的子菜单,它可以是 '/clients'
等。那么你只需使用 *ngIf
指令:
<ul *ngIf="location.includes('/clients')">
要检查当前 URL,您必须侦听路由器更改。因此,在您拥有 sidenav 内容的组件中,您需要订阅 router.events
属性.
import { Router, NavigationEnd } from '@angular/router';
import 'rxjs/add/operator/filter';
...
export class SidenavComponent {
location = '';
constructor(router: Router) {
router.events
.filter(event => event instanceof NavigationEnd)
.subscribe((event: NavigationEnd) => {
this.location = event.url
})
...
除了 NavigationEnd
路由器会发出多个其他事件,因此我们在上面的示例中过滤它们并在订阅后更新 location
属性
我已经想出如何使用布局方法来做到这一点。您可以查看使用此方法实现管理系统的示例 here
另一种选择是使用[hidden]
属性。我开始使用 *ngIf
但它重新创建了组件,在我的例子中,它重新触发了一些导致主要内容重绘的过滤。 [hidden]
允许我在不破坏组件的情况下有选择地显示内容。用法如下:
<mat-sidenav-container class="sidenav-container">
<mat-sidenav>
<div >
<div [hidden]="activeContent !== 'sidenav1'">
<p>SIDENAV 1</p>
</div>
<div [hidden]="activeContent !== 'sidenav2'">
<p>SIDENAV 2</p>
</div>
</div>
</mat-sidenav>
<mat-sidenav-content>
<p>MAIN CONTENT<p>
</mat-sidenav-content>
</mat-sidenav-container>
备注:
activeContent
是组件 class 上的一个 public 字段,其中包含 sidenav 名称(或者更具体地说,string literal union type 用于 design-time 类型检查)
- 如果您正在为 sidenav 使用
side
模式并且您的 sidenav 内容宽度不一致,您可能会发现主要内容不会调整大小以填充可用 space。我为此想出的最佳解决方案是当 sidenav 内容更改时在组件 class 中触发 this._sidenav.close().then(_ => this._sidenav.open());
。
我正在 Angular 开发单页应用程序 2. 我正在使用 angular material mat-sidenav 和 mat-toolbar。工具栏有 sidenav 切换按钮,用于打开 'Clients' 部分和 'Reports' 部分的按钮。这种结构在整个项目中很常见。
所以应用看起来像这样:
我必须根据路由器的当前状态更改 sidenav(和主字段)中的内容。因此,如果打开 'Clients' 部分,sidenav 应该会显示一些与客户端相关的小节。同样,对于 'Reports' 部分,只有与报告相关的小节应该可用。我该怎么做?
我通过检查 URL 路径是否包含某些指定部分来做到这一点。例如,如果你想为客户提供可见的子菜单,它可以是 '/clients'
等。那么你只需使用 *ngIf
指令:
<ul *ngIf="location.includes('/clients')">
要检查当前 URL,您必须侦听路由器更改。因此,在您拥有 sidenav 内容的组件中,您需要订阅 router.events
属性.
import { Router, NavigationEnd } from '@angular/router';
import 'rxjs/add/operator/filter';
...
export class SidenavComponent {
location = '';
constructor(router: Router) {
router.events
.filter(event => event instanceof NavigationEnd)
.subscribe((event: NavigationEnd) => {
this.location = event.url
})
...
除了 NavigationEnd
路由器会发出多个其他事件,因此我们在上面的示例中过滤它们并在订阅后更新 location
属性
我已经想出如何使用布局方法来做到这一点。您可以查看使用此方法实现管理系统的示例 here
另一种选择是使用[hidden]
属性。我开始使用 *ngIf
但它重新创建了组件,在我的例子中,它重新触发了一些导致主要内容重绘的过滤。 [hidden]
允许我在不破坏组件的情况下有选择地显示内容。用法如下:
<mat-sidenav-container class="sidenav-container">
<mat-sidenav>
<div >
<div [hidden]="activeContent !== 'sidenav1'">
<p>SIDENAV 1</p>
</div>
<div [hidden]="activeContent !== 'sidenav2'">
<p>SIDENAV 2</p>
</div>
</div>
</mat-sidenav>
<mat-sidenav-content>
<p>MAIN CONTENT<p>
</mat-sidenav-content>
</mat-sidenav-container>
备注:
activeContent
是组件 class 上的一个 public 字段,其中包含 sidenav 名称(或者更具体地说,string literal union type 用于 design-time 类型检查)- 如果您正在为 sidenav 使用
side
模式并且您的 sidenav 内容宽度不一致,您可能会发现主要内容不会调整大小以填充可用 space。我为此想出的最佳解决方案是当 sidenav 内容更改时在组件 class 中触发this._sidenav.close().then(_ => this._sidenav.open());
。