其實這是一個看一看 ui-router 的 wiki,再瞄一下 source code 就可以發現的 bug ,不過由於影響不是慎大,也沒有寫在 test spec 裡,它就這樣在 0.2.0 release 接近兩個月的現在還躺在那兒。
竹林中
陰影
昨天在忙 git-source (其實也就是在忙這個 blog),觀察到一件讓我非常在意的事情。
下面是一頁我在 localhost
測試嵌入 git-source 到頁面中的截圖,這頁一開進去,歷史記錄馬上就有三筆。
緊接著,我按一次「重新整理」,變成下面這樣:
此刻,我驚覺這不是一個小問題,弄不好可能會毀掉我的 git-source 專案…
搜索
我在應用 git-source 到 ngNoob 的初期就有發現到,點進一篇文章之後幾乎就無法用「上一頁」的方式點回來,因為有大量的歷史記錄被塞給瀏覽器。當時我以為是 Tumblr 或是這個 blog theme 的問題所以不以為意,事到如今…
難道是我的 git-source 出的包!?
首先必須要找出問題的來源,於是我在 code 中埋首好一陣子,嘗試各種能夠避免出現上述情況的方法(刪改大法!);同時也去 ui-router(git-source 的關鍵 module) 那邊看看他們的 example 跟我的寫法有什麼不同(已試過如果嵌入 ui-router 的 example 是不會有同樣現象發生)。
經過了一小時,不可以說是一無所獲,但尚無法掌握決定性的觸發原因.. 基本上已經鎖定在 .config
的時候,就差臨門一腳了。
此時我腦中浮現了一個我曾經看過(但也是不以為意)的 routing behavior。
首先 ui-router 設定如下:
// inside angular app config
$stateProvider
.state('route1', {
url: '/route1?this&is&a&test',
templateUrl: 'route1.html'
});
接著當你嘗試在網址列以
#/route1?test=1&is=2&this=3&a=4
存取 route1
的時候,你會看到 URL 自動被轉換成
#/route1?this=3&is=2&a=4&test=1
這不就是增加了一次 history 嗎!
真身
經過修改 code 進行交叉比對之後,確認就是在上述的設定下會有被大量幅報 browser history 的現象,而每個內嵌的 iframe 剛好報一個。
這是 ui-router 有意要讓它發生的嗎?重重的疑惑驅始我去 trace ui-router 的 source code…
ui-router 內的 state change 觸發都是由
$state.transitionTo
負責的,而它有參數可以決定本次的 state transition 要不要 update location (即改變 URL)。
循著這個概念,我就直接往與 transitionTo
有關的地方找去,還順便去 github 上 blame 了一下…
於是我找到了關鍵的 commit。
(Bug) Demo
下面的 demo 因為牽涉到 $location ,建議開到 Plunker 去用另開視窗的模式觀看。
現象
在 發現 / 搜索 bug 過程中擔任關鍵角色的現象。
下方的 location change log
會在每次準備進行 state transition 的時候清空 (也就是 $stateChangeStart
的時候),讓我們可以清楚的觀察到 URL 改變的觸發情況。
直搗黃龍
直接使用 $state.transitionTo()
來做第三個參數代入 false
的 state transition。如果 $state.transitionTo()
真的沒有問題,理應下方的 location change log
在切換 route 時會保持空白。
後記
ui-router 還是很好用啦…
然後我已經 report issue 了,只好先用 fork 來的 custom build 撐一下: