最近遇到的問題是咱們在一個查詢列表頁面上對該頁面的的某條內容進行編輯或者新增以後再跳回的話,咱們的原頁面便會從新加載,這個不是很人性化,爲此咱們想要實現的效果是,在編輯和修改完成以後,返回原界面時原內容保留。實現效果以下所示。java
編輯前
緩存
編輯後
app
在這裏咱們使用了一種叫作路由複用的機制來實現。ide
大概的原理是,通常狀況下,在路由離開時就會銷燬該路由的組件,再次跳轉時會從新初始化,調用nginit()方法,可是咱們如今是需求是保留路由的原狀態,爲此咱們須要重寫RouteReuseStrategy接口,該接口實現路由複用策略。函數
shouldDetach 是否容許複用路由
store 當路由離開時會觸發,存儲路由
shouldAttach 是否容許還原路由
retrieve 獲取存儲路由
shouldReuseRoute 進入路由觸發,是否同一路由時複用路由this
在該項目中咱們的具體實現代碼以下spa
export class SimpleReuseStrategy implements RouteReuseStrategy { _cacheRouters: { [key: string]: any } = {}; shouldDetach(route: ActivatedRouteSnapshot): boolean { // 默認對全部路由複用 可經過給路由配置項增長data: { keep: true }來進行選擇性使用 // {path: 'search', component: SearchComponent, data: {keep: true}}, if (route.data.keep) { return true; } else { return false; } } store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { // 在懶加載的時候使用,data.key存儲路由快照&組件當前實例對象 // path等同RouterModule.forRoot中的配置 this._cacheRouters[route.data.key] = { snapshot: route, handle: handle }; } shouldAttach(route: ActivatedRouteSnapshot): boolean { // 在緩存中有的都認爲容許還原路由 return !!route.routeConfig && !!this._cacheRouters[route.data.key]; } retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { // 從緩存中獲取快照,若無則返回null if (!route.routeConfig || route.routeConfig.loadChildren || !this._cacheRouters[route.data.key]) { return null; } return this._cacheRouters[route.data.key].handle; } shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { // 同一路由時複用路由 return future.routeConfig === curr.routeConfig; } }
而後在咱們app.module中引進來,以下,該處應該是要和AppRoutingModule
在一個module裏,當前項目中其餘的子模塊中使用不產生效果:code
{ provide: RouteReuseStrategy, useClass: SimpleReuseStrategy }
對於要服用的路由咱們以下使用component
{ path: '', component: InstrumentCategoryIndexComponent, data: {keep: true, key: 'instrumentCategory'}},
1.第一個問題是如何使得跳轉後頁面的查詢和分頁信息不變,只更新數據。router
解決方法:
因爲使用了路由服用機制以後,便不執行nginit
的方法了因此咱們在構造函數中加上對路由的監聽事件,當路由切換的時候咱們使用原有的分頁和查詢參數對數據進行更新。
params; constructor( private instrumentCategoryService: InstrumentCategoryService, @Inject('DEFAULT_SIZE_CONFIG') private size: number, private adminComponent: AdminComponent, private instrumentAliasService: InstrumentAliasService, private instrumentSpecificationService: InstrumentSpecificationService, private router: Router ) { // 路由複用以後從新加載數據 this.router.events.subscribe(() => { if (this.params) { this.page(); } }); } ngOnInit() { // 初始化參數 this.params = { page: 0, // 默認是第0頁 size: this.size, // 獲取默認的每頁大小 name: null, // 姓名 subjectCategory: null, // 學科類別 }; this.page(); }
2.惰性加載下路由複用的失效
當使用路由服用的策略以後,出現按照以前的策略失效,產生以下錯誤。這個問題花了好久也沒解決後來找喜碩幫忙解決,緣由是咱們使用了惰性加載,在惰性加載的時候route.routeConfig.path
加載就爲空,因此在存儲的時候後產生錯誤。
後來的解決方案以下,咱們在路由的數據上新增一個key值用這個key的值來存儲咱們的複用的路由如上代碼所示。