Angular 2.0.1:简化复杂的导航组件

时间:2016-09-28 15:16:13

标签: angular angular2-routing angular2-router3

如何使导航组件与非平凡的应用程序保持同步?例如,在Angular 2's simple Tour of Heroes application中,app.component.ts具有静态(即不变)声明性导航:

<h1>{{title}}</h1>
<nav>
  <a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
  <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>

但在更复杂的应用程序中,导航组件通常是动态的。在我的情况下,nav sidenav back 按钮,特定于组件的操作和用户信息;并且, sidenav 操作会根据用户的角色而改变。这是一个相当典型的场景 - 想想谷歌Gmail,收件箱,日历,文档等。

现在,我的nav位于单个my-header组件中,对当前组件和用户角色进行了大量*ngIf测试 - 这是一个丑陋的噩梦:

<md-toolbar color="primary" class="fixed-toolbar">
  <div *ngIf="isAuthenticated()">

    <md-menu #mainmenu="mdMenu">
      <a md-menu-item routerLink="/marketplaces" routerLinkActive="active">Marketplaces</a>
      <a md-menu-item routerLink="/people" routerLinkActive="active">People</a>
      <span *ngIf="isAdministrator()">
        <md-divider></md-divider>
        <a md-menu-item routerLink="/accounts" routerLinkActive="active">Accounts</a>
      </span>
    </md-menu>
    <button *ngIf="_navigation?.toolbar == 'default'" md-icon-button [md-menu-trigger-for]="mainmenu">
      <md-icon>menu</md-icon>
    </button>

    <button *ngIf="_navigation?.toolbar == 'market'" md-icon-button
            (click)="closeAndReturn($event, 'marketplaces')"
            aria-label="Back to Marketplaces">
      <md-icon>close</md-icon>
    </button>

    <button *ngIf="_navigation?.toolbar == 'person'" md-icon-button
            (click)="closeAndReturn($event, 'users')"
            aria-label="Back to People">
      <md-icon>close</md-icon>
    </button>
  </div>

  <!-- ^^^ nightmare continues vvv -->

my-header组件只包含在app.component.html

<my-header></my-header>
<router-outlet></router-outlet>
<my-footer></my-footer>

my-header组件和my-footer组件都不在路由器树中,因此my-header注入ActivatedRoute始终是根节点,这意味着我甚至无法转换绝对返回导航:

(click)="closeAndReturn($event, 'marketplaces')"

相对导航:

(click)="closeAndReturn($event, '../')"

这意味着复制这个组件中的路由器树以保持同步 - 这显然不是正确的事情 ...

关于如何解决这个问题的想法,可能是超常常的挑战,即保持导航组件与复杂的应用程序同步?

1 个答案:

答案 0 :(得分:0)

要解决相对导航问题,请在路由器中侦听事件并捕获URL:

  constructor(private _router: Router) {
    this._router.events
            .filter( e => e instanceof NavigationEnd )
            .subscribe( e => this._currentUrl = e.url );
  }

然后,修剪最后一个网址段以提升一个级别:

  closeAndReturn(event?) {
    const url = this._currentUrl;
    const path = url.slice(0, url.lastIndexOf('/'));

    this._router.navigate([path]);
  }

HTML更清晰,重复性更低:

<button md-icon-button (click)="closeAndReturn($event)" aria-label="Back">
  <md-icon>close</md-icon>
</button>

但HTML中仍有很多重复的路由器信息。