Angular 使用 RouteReuseStrategy (路由复用策略) 实现后台 TAB 标签

我们后台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 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!