Angular 使用 RouteReuseStrategy (路由複用策略) 實現後臺 TAB 標籤

Donjan發表於2019-12-18

我們後臺TAB標籤切換的時候需要儲存原標籤頁的狀態,當再次切換回來的時候仍然一致,這裡就要用到路由複用策略儲存快照。

抽象類RouteReuseStrategy在@angular/router包

abstract class RouteReuseStrategy {
  abstract shouldDetach(route: ActivatedRouteSnapshot): boolean
  abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void
  abstract shouldAttach(route: ActivatedRouteSnapshot): boolean
  abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null
  abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean
}

我們建立app-reusestrategy.module.ts實現該類。

excludePath為不使用策略的路由地址
如果在還原快照的時候需要重新整理某部分資料,只需要放入init方法裡。例如src/app/views/user/list.component.ts

  init() {
    this.getList();
    this.getRoleList();
  }

src/app/app-routing.module.ts匯入

import { ReuseStrategy } from './app-reusestrategy.module';

並新增到providers

{ provide: RouteReuseStrategy, useClass: ReuseStrategy }

然後在src/app/app.component.ts匯入

import { ReuseStrategy } from './app-reusestrategy.module';

宣告一個menuList儲存tab標籤列表
當重新整理網頁的時候把當前頁面放入tab

  pushCurrTab() {
    const currPerm = this.permissions.find(e => e.url == this.router.url);
    if (currPerm) {
      this.titleService.setTitle(currPerm.display_name);
      this.menuList.push({
        title: currPerm.display_name,
        path: currPerm.url,
        select: true
      });
    } else {
      this.menuList.push({
        title: '後臺首頁',
        path: '/index',
        select: true
      });
    }
  }

訂閱路由事件NavigationEnd,如果存在menuList就啟用,不存在就新增

 onNavigationEnd() {
    this.router.events.subscribe((event) => {
      if (event instanceof NavigationEnd) {
        const path = event.url;
        let perm = this.permissions.find(e => e.url == path);
        if (!perm) {
          if (path === '/index') {
            perm = {
              url: path,
              display_name: '後臺首頁'
            };
          } else {
            return;
          }
        }
        this.titleService.setTitle(perm.display_name);
        this.menuList.forEach(p => p.select = false);
        const exitMenu = this.menuList.find(e => e.path == perm.url);
        if (exitMenu) {// 如果存在不新增,當前表示選中
          this.menuList.forEach(p => p.select = p.path == exitMenu.path);
          return;
        }
        this.menuList.push({
          title: perm.display_name,
          path: perm.url,
          select: true
        });
      }
    });
  }

關閉tab標籤

  closeUrl(path, select) {
    // 當前關閉的是第幾個路由
    let index = this.menuList.findIndex(p => p.path == path);
    // 如果只有一個不可以關閉
    if (this.menuList.length == 1 || select == false) {
      return;
    }
    this.menuList = this.menuList.filter(p => p.path != path);
    // 刪除複用
    delete ReuseStrategy.handlers[path];
    if (!select) {
      return;
    }
    // 顯示上一個選中
    index = index === 0 ? 0 : index - 1;
    let menu = this.menuList[index];
    this.menuList.forEach(p => p.select = p.path == menu.module);
    // 顯示當前路由資訊
    this.router.navigate([menu.path]);
  }

部落格:《PHP 微服務練兵》系列教程

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章