結論:
結論放最上面,送給匆匆查資料的你:
- 同時使用延遲加載 + 路由復用,一定不能使用route.routeConfig.path做key去緩存,否則會死得難看。
- 經實測(我沒有完全去解讀源代碼),將緩存的key改為下面的函數計算可行。
private getRouteUrl(route: ActivatedRouteSnapshot) { return route['_routerState'].url.replace(/\//g, '_') + '_' + (route.routeConfig.loadChildren || route.routeConfig.component.toString().split('(')[0].split(' ')[1] ); }
基礎版
關於angular2開始的路由復用網上教程很多,例如: https://www.softwarearchitekt.at/post/2016/12/02/sticky-routes-in-angular-2-3-with-routereusestrategy.aspx。
這個最初級的版本有一個問題:在延遲加載模式下,以route.couteConfig.path去做為緩存key是不可取的。經調試,path指的是配置在路由中的路由規則,不同模塊有相同規則的機率相當在,比如每個模塊可能都有 ' ' 做默認路由。
(這個版本挺有意思的,當時坑了我很久:從一個模塊的默認路由跳到另一模塊默認路由,由於path都是‘’,所以直接從緩存中把前一模塊原來的緩存取了出來,導致看到的效果就是點了routerLink跳轉沒反應,也不報錯。因為之前使用routerLink時記得要添加模塊引用。好長時間,我以為是routerLink沒有配置好,或者angular6升級了什么被遺漏了。根本就沒有往路由上想!)
改進版
參考:https://www.cnblogs.com/lovesangel/p/7853364.html
這個版本意識到了上面的問題,采用用路由的url做路徑,其實問題依然沒解決,經調試還是會出現問題:
Uncaught Error: Uncaught (in promise): Error: Cannot reattach ActivatedRouteSnapshot created from a different route |
在參考了https://stackoverflow.com/questions/41584664/error-cannot-reattach-activatedroutesnapshot-created-from-a-different-route后,在retrive時加上
if (route.routeConfig.loadChildren) return null;
依然不能解決問題,基本調試如下:
這引起了我的注意,因為這兩個組件的路由參數是一樣的:
path: '', component: ProjectDisplayComponent, children: [ { path: '', component: ProjectHomeComponent },
shouldAttach方法也進了兩次:
路由要復用,兩個組件肯定都要進緩存的,用同樣的key肯定會出問題的,於是在改進版上做修改如下:
private getRouteUrl(route: ActivatedRouteSnapshot) {
return route['_routerState'].url.replace(/\//g, '_')
+ '_' + (route.routeConfig.loadChildren || route.routeConfig.component.toString().split('(')[0].split(' ')[1] );
}
后面多出的一行代碼:用於區分延遲加載時的模塊路徑,以及默認子組件與父組件。至此,問題解決(而且,可以去除 "if (route.routeConfig.loadChildren) return null"這一句。
經過測試:的確默認子組件及父組件都有緩存:
如果不加藍色框線部分區分,存取難免出現沖突。
————————————————————————————————————————————————————————————————
禮尚往來,由於此文之前也參考了前面的人的改進方案,故傳承改進,希望能幫到你。