淺談Angular路由復(fù)用策略
一、引言
路由在執(zhí)行過程中對(duì)組件無(wú)狀態(tài)操作,即路由離退時(shí)組件狀態(tài)也一并被刪除;當(dāng)然在絕大多數(shù)場(chǎng)景下這是合理的。
但有時(shí)一些特殊需求會(huì)讓人半死亡狀態(tài),當(dāng)然這一切都是為了用戶體驗(yàn);一種非常常見場(chǎng)景,在移動(dòng)端中用戶通過關(guān)鍵詞搜索商品,而死不死的這樣的列表通常都會(huì)是自動(dòng)下一頁(yè)動(dòng)作,此時(shí)用戶好不容易滾動(dòng)到第二頁(yè)并找到想要看的商品時(shí),路由至商品詳情頁(yè),然后一個(gè)后退……用戶懵逼了。
Angular路由與組件一開始就透過 RouterModule.forRoot
形成一種關(guān)系,當(dāng)路由命中時(shí)利用ComponentFactoryResolver
構(gòu)建組件,這是路由的本質(zhì)。
而每一個(gè)路由并不一定是一次性消費(fèi),Angular 利用 RouteReuseStrategy
貫穿路由狀態(tài)并決定構(gòu)建組件的方式;當(dāng)然默認(rèn)情況下(DefaultRouteReuseStrategy
)像開頭說(shuō)的,一切都不進(jìn)行任何處理。
RouteReuseStrategy 從2就已經(jīng)是實(shí)驗(yàn)性,當(dāng)前依然如此,這么久應(yīng)該是可信任。
二、RouteReuseStrategy
RouteReuseStrategy
我稱它為:路由復(fù)用策略;并不復(fù)雜,提供了幾種辦法通俗易懂的方法:
- shouldDetach 是否允許復(fù)用路由
- store 當(dāng)路由離開時(shí)會(huì)觸發(fā),存儲(chǔ)路由
- shouldAttach 是否允許還原路由
- retrieve 獲取存儲(chǔ)路由
- shouldReuseRoute 進(jìn)入路由觸發(fā),是否同一路由時(shí)復(fù)用路由
這看起來(lái)就像是一個(gè)時(shí)間軸關(guān)系,用一種白話文像是這樣:把路由 /list 設(shè)置為允許復(fù)用(shouldDetach),然后將路由快照存在 store 當(dāng)中;當(dāng) shouldReuseRoute 成立時(shí)即:再次遇到 /list 路由后表示需要復(fù)用路由,先判斷 shouldAttach 是否允許還原,最后從 retrieve 拿到路由快照并構(gòu)建組件。
當(dāng)理解這一原理時(shí),假如我們拿開頭搜索列表返回的問題就變得非常容易解決。
三、一個(gè)示例
誠(chéng)如上面說(shuō)明的,只需要實(shí)現(xiàn) RouteReuseStrategy 接口即可自定義一個(gè)路由利用策略。
1、創(chuàng)建策略
import {RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle} from '@angular/router'; export class SimpleReuseStrategy implements RouteReuseStrategy { _cacheRouters: { [key: string]: any } = {}; shouldDetach(route: ActivatedRouteSnapshot): boolean { return true; } store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { this._cacheRouters[route.routeConfig.path] = { snapshot: route, handle: handle }; } shouldAttach(route: ActivatedRouteSnapshot): boolean { return !!this._cacheRouters[route.routeConfig.path]; } retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return this._cacheRouters[route.routeConfig.path].handle; } shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { return future.routeConfig === curr.routeConfig; } }
定義一個(gè) _cacheRouters 用于緩存數(shù)據(jù)(路由快照及當(dāng)前組件實(shí)例對(duì)象)。
- shouldDetach 直接返回 true 表示對(duì)所有路由允許復(fù)用
- store 當(dāng)路由離開時(shí)會(huì)觸發(fā)。按path作為key存儲(chǔ)路由快照&組件當(dāng)前實(shí)例對(duì)象;path等同RouterModule.forRoot中的配置。
- shouldAttach 若 path 在緩存中有的都認(rèn)為允許還原路由
- retrieve 從緩存中獲取快照,若無(wú)則返回null
- shouldReuseRoute 進(jìn)入路由觸發(fā),判斷是否同一路由
2、注冊(cè)
最后將策略注冊(cè)到模塊當(dāng)中:
providers: [ { provide: RouteReuseStrategy, useClass: SimpleReuseStrategy } ]
假設(shè)我們有這么一個(gè)路由配置:
RouterModule.forRoot([ { path: 'search', component: SearchComponent }, { path: 'edit/:id', component: EditComponent } ])
搜索組件用于搜索動(dòng)作,并在根據(jù)搜索結(jié)果跳轉(zhuǎn)至編輯頁(yè),保存后又回到最后搜索結(jié)果的狀態(tài)(這部分代碼我就不貼有興趣見 plnkr)。
四、結(jié)論
上述只是一個(gè)簡(jiǎn)單的拋磚引玉作用,實(shí)則對(duì)于復(fù)用的判斷會(huì)更復(fù)雜、滾動(dòng)條位置、緩存清理等等。
善用這種路由復(fù)用策略機(jī)制可以解決很多Web體驗(yàn)上的問題。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Angularjs制作簡(jiǎn)單的路由功能demo
- AngularJS 路由詳解和簡(jiǎn)單實(shí)例
- AngularJS路由實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)實(shí)例
- Angular 4.x 路由快速入門學(xué)習(xí)
- angular.js 路由及頁(yè)面?zhèn)鲄⑹纠?/a>
- 使用AngularJS對(duì)路由進(jìn)行安全性處理的方法
- 詳解angular2實(shí)現(xiàn)ng2-router 路由和嵌套路由
- AngularJS監(jiān)聽路由的變化示例代碼
- angular中使用路由和$location切換視圖
- AngularJS 路由和模板實(shí)例及路由地址簡(jiǎn)化方法(必看)
相關(guān)文章
AngularJS入門教程之MVC架構(gòu)實(shí)例分析
這篇文章主要介紹了AngularJS的MVC架構(gòu),結(jié)合實(shí)例形式重點(diǎn)分析了ng-controller聲明并使用控制器的操作技巧與控制器作用域的相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-11-11Angular2使用Angular CLI快速搭建工程(一)
這篇文章主要介紹了Angular2使用Angular CLI快速搭建工程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05基于angular6.0實(shí)現(xiàn)的一個(gè)組件懶加載功能示例
這篇文章主要介紹了基于angular6.0實(shí)現(xiàn)的一個(gè)組件懶加載功能示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-04-04AngularJS Bootstrap詳細(xì)介紹及實(shí)例代碼
本文主要介紹AngularJS Bootstrap,這兩對(duì)AngularJS Bootstrap的基礎(chǔ)知識(shí)做了詳細(xì)講解,并提供簡(jiǎn)單示例,有需要的小伙伴可以參考下2016-07-07Angular.js ng-file-upload結(jié)合springMVC的使用教程
這篇文章主要給大家介紹了關(guān)于Angular.js文件上傳控件ng-file-upload結(jié)合springMVC的使用教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-07-07Angular.Js之Scope作用域的學(xué)習(xí)教程
這篇文章主要給大家分享了關(guān)于Angular.Js之Scope作用域的學(xué)習(xí)教程 ,文中通過多個(gè)示例代碼介紹的非常詳細(xì),相信對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-04-04