Angular路由複用策略RouteReuseStrategy(經常使用於實現Tab頁籤切換頁面)

使用場景

路由切換時,使用快照。常應用在tab頁籤切換時,原頁籤頁面的填寫的信息狀態保留。原理就是使用路由複用策略,在切換路由時,將路由的快照存放起來,下次再打開此路由時加載對應快照。css

路由複用

新建RouteReuseStrategy

新建一個CustomReuseStrategy.ts 實現接口 RouteReuseStrategy
查看 RouteReuseStrategy 的 API 瞭解更多html

import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';

export class CustomReuseStrategy implements RouteReuseStrategy {

    public static handlers: { [key: string]: DetachedRouteHandle } = {};

    /** 刪除緩存路由快照的方法 */
    public static deleteRouteSnapshot(path: string): void {
        const name = path.replace(/\//g, '_');
        if (CustomReuseStrategy.handlers[name]) {
            delete CustomReuseStrategy.handlers[name];
        }
    }

    /** 表示對全部路由容許複用 若是你有路由不想利用能夠在這加一些業務邏輯判斷 */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        // console.debug('shouldDetach======>', route);
        return true;
    }

    /** 當路由離開時會觸發。按path做爲key存儲路由快照&組件當前實例對象 */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        // console.debug('store======>', route, handle);
        CustomReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
    }

    /** 若 path 在緩存中有的都認爲容許還原路由 */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        // console.debug('shouldAttach======>', route);
        return !!CustomReuseStrategy.handlers[this.getRouteUrl(route)];
    }

    /** 從緩存中獲取快照,若無則返回nul */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        // console.debug('retrieve======>', route);
        if (!CustomReuseStrategy.handlers[this.getRouteUrl(route)]) {
            return null;
        }

        return CustomReuseStrategy.handlers[this.getRouteUrl(route)];
    }

    /** 進入路由觸發,判斷是否同一路由 */
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        // console.debug('shouldReuseRoute======>', future, curr);
        return future.routeConfig === curr.routeConfig &&
            JSON.stringify(future.params) === JSON.stringify(curr.params);
    }

    /** 使用route的path做爲快照的key */
    getRouteUrl(route: ActivatedRouteSnapshot) {
        const path = route['_routerState'].url.replace(/\//g, '_');
        return path;
    }

}

app.module.ts進行註冊typescript

import { NgModule } from '@angular/core';
import { RouteReuseStrategy } from '@angular/router';
import { AppComponent } from './app.component';
import { CustomReuseStrategy } from './CustomReuseStrategy';

@NgModule({
  declarations: [
    AppComponent
],
  imports: [
    // your imports
  ],
  providers: [
    { provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

以上基本實現了全部路由複用。bootstrap

刪除路由快照

可是,若是切換路由時,須要路由重載而不是快照。則須要實現如下代碼,刪除對應的快照。
在tab.component.ts定義刪除快照方法,切換tab時進行路由加載前進行調用便可。api

import { Component, OnInit } from '@angular/core';
import { CustomReuseStrategy } from '../r';

@Component({
  selector: 'tabpage',
  templateUrl: './tabpage.component.html',
  styleUrls: ['./tabpage.component.css'],
  providers: [CustomReuseStrategy]
})
export class TodoComponent implements OnInit{
  constructor() {}

  ngOnInit(): void {}

  changeTab() {
    // 刪除快照
    this.deleteRouteSnapshot();
    // tab切換代碼,路由跳轉代碼
    // ...
  }

  /** 路由加載前可手動刪除路由快照,切換路由則不會使用快照 */
  deleteRouteSnapshot() {
    CustomReuseStrategy.deleteRouteSnapshot('/todolazy');
  }
}

懶加載的路由複用

以上寫法,適用於普通路由、路由懶加載(lazy loading module)、子路由、子路由懶加載(lazy loading
module)。親測可用
RouteReuseStrategy can working with lazy loading feature modules

問題

若是遇到 `Error: Cannot reattach ActivatedRouteSnapshot created from a
different route` 這個問題,能夠參考 :

https://stackoverflow.com/que...緩存

參考文章

http://www.cnblogs.com/lslgg/...
https://www.cnblogs.com/loves...
https://ng-alain.com/componen...app

相關文章
相關標籤/搜索