美文网首页我爱编程
Angular 2+ 中,懒加载 + 辅助路由 + 路由策略 三

Angular 2+ 中,懒加载 + 辅助路由 + 路由策略 三

作者: 环零弦 | 来源:发表于2018-02-05 11:47 被阅读0次

    Angular 2+ 中辅助路由的应用之前也已经写过了,大概如下:
    代码中:

    <a [routerLink]="[{outlets:{primary:'components/buttons',aux:'pages/login'}}]">测试1</a>
    

    地址栏中:

    http://localhost:4200/#/components/buttons(aux:pages/404)
    

    路由设置:

    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    // Import Containers
    import {
    FullLayoutComponent,
    SimpleLayoutComponent
    } from './containers';
    
    export const routes: Routes = [
    {
        path: 'components',
        loadChildren: './views/components/components.module#ComponentsModule'
    },
    {
        path: 'editors',
        loadChildren: './views/editors/editors.module#EditorsModule'
    },
    {
        path: 'pages',
        component: SimpleLayoutComponent,
        outlet: 'aux',
        data: {
        title: 'Pages'
        },
        children: [
        {
            path: '',
            loadChildren: './views/pages/pages.module#PagesModule',
        }
        ]
    }
    ];
    
    @NgModule({
    imports: [ RouterModule.forRoot(routes) ],
    exports: [ RouterModule ]
    })
    export class AppRoutingModule {}
    

    界面:
    In app.component.html

    <app-header></app-header>
    <div class="app-body">
      <app-sidebar></app-sidebar>
      <!-- Main content -->
      <main class="main">
        <!-- Breadcrumb -->
        <ol class="breadcrumb">
          <app-breadcrumbs></app-breadcrumbs>
        </ol>
        <div class="container-fluid">
          <router-outlet></router-outlet>
        </div><!-- /.conainer-fluid -->
      </main>
      <app-aside></app-aside>
    </div>
    <app-footer></app-footer>
    

    In app-aside.component.html

    <aside class="aside-menu">
      <router-outlet name="aux"></router-outlet>
    </aside>
    

    In simple-layout.component.ts

    import { Component } from '@angular/core';
    @Component({
      template: '<router-outlet></router-outlet>',
    })
    export class SimpleLayoutComponent { }
    

    In editors-routing.module.ts

    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    const routes: Routes = [
      {
        path: '',
        data: {
          title: 'Editors'
        },
        children: [
          {
            path: 'text-editors',
            loadChildren: './text-editors/text-editors.module#TextEditorsModule'
          },
          {
            path: 'code-editors',
            loadChildren: './code-editors/code-editors.module#CodeEditorsModule'
          }
        ]
      }
    ];
    @NgModule({
      imports: [RouterModule.forChild(routes)],
      exports: [RouterModule]
    })
    export class EditorsRoutingModule {}
    

    之前的路由策略:

    export class CustomReuseStrategy implements RouteReuseStrategy {
        handlers: {[key: string]: DetachedRouteHandle} = {};
        shouldDetach(route: ActivatedRouteSnapshot): boolean {
            console.debug('CustomReuseStrategy:shouldDetach', route);
            return true;
        }
        store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
            console.debug('CustomReuseStrategy:store', route, handle);
            this.handlers[route.routeConfig.path] = handle;
        }
        shouldAttach(route: ActivatedRouteSnapshot): boolean {
            console.debug('CustomReuseStrategy:shouldAttach', route);
            return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
        }
        retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
            console.debug('CustomReuseStrategy:retrieve', route);
            return this.handlers[route.routeConfig.path];//从暂存处取回
        }
        shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
            //在此处可以取得跳转前和跳转后的路由路径
            console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
            return future.routeConfig === curr.routeConfig;
        }
    }
    

    加上路由策略以后就会使得带辅助路由的跳转报错:

    Cannot reattach ActivatedRouteSnapshot created from a different route

    这个问题之前在 AngularGit 上的那个 issueCannot reattach ActivatedRouteSnapshot created from a different route 存在了一年多,并没有解决,包括查阅了网上的各种偏方,也并不好使,后来好不容易百度到这样的解决方案:

    后来的路由策略:

    import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
    
    export class SimpleReuseStrategy implements RouteReuseStrategy {
      public static handlers: { [key: string]: DetachedRouteHandle } = {};
      /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */
      public shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return true;
      }
      /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */
      public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        SimpleReuseStrategy.handlers[route.routeConfig.path] = handle
      }
      /** 若 path 在缓存中有的都认为允许还原路由 */
      public shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!route.routeConfig && !!SimpleReuseStrategy.handlers[route.routeConfig.path]
      }
      /** 从缓存中获取快照,若无则返回nul */
      public retrieve_bak(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        if (!route.routeConfig) {
          return null
        }
        return SimpleReuseStrategy.handlers[route.routeConfig.path]
      }
      public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        if (!route.routeConfig) {
          return null;
        }
        if (route.routeConfig.loadChildren) {
          return null;
        }
        return SimpleReuseStrategy.handlers[route.routeConfig.path];
      }
      /** 进入路由触发,判断是否同一路由 */
      public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig
      }
    }
    

    实践证明这个并不会报错,是可以用的,Payload 就是这个函数:

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
      if (!route.routeConfig) return null;
      if(route.routeConfig.loadChildren) return null;
      return this.handlers[route.routeConfig.path];
    }
    

    总之 Angular 的路由是极其重要的组件,也是存在问题比较多的组件。

    参考资料:

    相关文章

      网友评论

        本文标题:Angular 2+ 中,懒加载 + 辅助路由 + 路由策略 三

        本文链接:https://www.haomeiwen.com/subject/fkybzxtx.html