【问题标题】:Angular 2.0.1: simplifying a complex navigation componentAngular 2.0.1:简化复杂的导航组件
【发布时间】:2016-09-28 15:16:12
【问题描述】:

如何保持导航组件与非平凡应用程序同步?例如,在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 按钮、特定于组件的 actions 和用户信息;而且,sidenavactions 会根据用户的角色而变化。这是一个相当典型的场景——想想 Google 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 始终是根节点,这意味着我什至无法转换绝对back 导航:

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

到相对导航:

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

这意味着在这个组件中复制路由器树以保持同步——这显然不是正确的做法...

关于如何解决这个可能是超级常见的挑战,让导航组件与复杂的应用程序保持同步,有什么想法吗?

【问题讨论】:

    标签: angular angular2-routing angular2-router3


    【解决方案1】:

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

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

    然后,修剪最后一个 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 中仍然有很多重复的路由器信息。

    【讨论】:

      猜你喜欢
      • 2020-07-31
      • 1970-01-01
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多