使用 Angular RouteReuseStrategy 快取組件
Cache components with Angular RouteReuseStrategy
RouteReuseStrategy provider 允許我們控制 Angular 路由和組件生命周期的行為,
當我們在組件間切換的時候,Angular都會銷毀上一個組件,并且創建一個新的組件,在大多數情況下,我們可能不想讓它這樣作業,因為每次加載一個組件,可能會有很多類似HTTP請求一樣的昂貴的操作,
這時候就需要RouteReuseStrategy了,
RouteReuseStrategy是什么
RouteReuseStrategy介面宣告了5個方法,
shouldReuseRoute
這個方法每次切換路由時都會被呼叫,future引數是將要離開的路由,curr引數是將要加載的路由,如果這個方法回傳true,路由將不會跳轉(意味著路由沒有發生變化),如果它回傳false,則路由發生變化并且其余方法會被呼叫,
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
// 默認行為
return future.routeConfig === curr.routeConfig;
}
shouldAttach
路由剛剛被打開,當我們加載到這個路由的組件上時,shouldAttach會被呼叫,一旦組件被加載這個方法都會被呼叫,如果這個方法回傳true,retrieve方法將會被呼叫,否則這個組件將會被重新創建,
shouldAttach(route: ActivatedRouteSnapshot): boolean;
retrieve
當shouldAttach方法回傳true時這個方法會被呼叫,提供當前路由的引數(剛打開的路由),并且回傳一個快取的RouteHandle,如果回傳null表示沒有效果,我們可以使用這個方法手動獲取任何已被快取的RouteHandle,框架不會自動管理它,需要我們手動實作,
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null;
shouldDetach
當離開當前路由時這個方法會被呼叫,如果回傳true,store方法會被呼叫,
shouldDetach(route: ActivatedRouteSnapshot): boolean;
store
這個方法當且僅當shouldDetach方法回傳true時被呼叫,我們可以在這里具體實作如何快取RouteHandle,在這個方法中快取的內容將會被用在retrieve方法中,它提供了我們離開的路由和RouteHandle,
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void;
示例
src/services/route-strategy.service.ts:
import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';
export class RouteStrategyService implements RouteReuseStrategy {
public static handlers: { [key: string]: DetachedRouteHandle } = {};
public static deleteRouteSnapshot(path: string): void {
const name = path.replace(/\//g, '_');
if (RouteStrategyService.handlers[name]) {
delete RouteStrategyService.handlers[name];
}
}
/**
* 判斷當前路由是否需要快取
* 這個方法回傳false時則路由發生變化并且其余方法會被呼叫
* @param {ActivatedRouteSnapshot} future
* @param {ActivatedRouteSnapshot} curr
* @returns {boolean}
* @memberof CacheRouteReuseStrategy
*/
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig
&& JSON.stringify(future.params) === JSON.stringify(curr.params);
}
/**
* 當離開當前路由時這個方法會被呼叫
* 如果回傳 true 則 store 方法會被呼叫
* @param {ActivatedRouteSnapshot} route
* @returns {boolean}
* @memberof CacheRouteReuseStrategy
*/
public shouldDetach(route: ActivatedRouteSnapshot): boolean {
return true;
}
/**
* 將路由寫入快取
* 在這里具體實作如何快取 RouteHandle
* 提供了我們離開的路由和 RouteHandle
* @param {ActivatedRouteSnapshot} route
* @param {DetachedRouteHandle} detachedTree
* @memberof CacheRouteReuseStrategy
*/
public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {
RouteStrategyService.handlers[this.getPath(route)] = detachedTree;
}
/**
* 路由被導航 如果此方法回傳 true 則觸發 retrieve 方法
* 如果回傳 false 這個組件將會被重新創建
* @param {ActivatedRouteSnapshot} route
* @returns {boolean}
* @memberof CacheRouteReuseStrategy
*/
public shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!RouteStrategyService.handlers[this.getPath(route)];
}
/**
* 從快取讀取cached route
* 提供當前路由的引數(剛打開的路由),并且回傳一個快取的 RouteHandle
* 可以使用這個方法手動獲取任何已被快取的 RouteHandle
* @param {ActivatedRouteSnapshot} route
* @returns {(DetachedRouteHandle | null)}
* @memberof CacheRouteReuseStrategy
*/
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
return RouteStrategyService.handlers[this.getPath(route)] || null;
}
private getPath(route: ActivatedRouteSnapshot): string {
// tslint:disable-next-line: no-string-literal
const path = route['_routerState'].url.replace(/\//g, '_');
return path;
}
}
src/app/app.module.ts:
import { RouteReuseStrategy } from '@angular/router';
import { RouteStrategyService } from '../services/route-strategy.service';
@NgModule({
...
providers: [
...
{ provide: RouteReuseStrategy, useClass: RouteStrategyService }
],
bootstrap: [AppComponent]
})
export class AppModule { }
以上示例運行時會快取所有路由組件,
實作比如標簽頁效果時,關閉標簽頁,呼叫RouteStrategyService中的deleteRouteSnapshot方法洗掉已快取的頁面即可,
這里可能會有個問題,如果你不想用這個路由快取了,請務必洗掉掉app.module.ts中的providers,而不是將RouteStrategyService的shouldReuseRoute始終return true;這樣會出現路由跳轉頁面不跳轉的問題,原因暫時未知,
以下是運行效果圖:

The end...
Last updated by Jehorn, 11/1/2019
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/177548.html
標籤:JavaScript
