在談路由機制前有必要先提一下現在比較流行的單頁面應用,就是所謂的single page APP。為了實現無刷新的視圖切換,我們通常會用ajax請求從后臺取數據,然后套上HTML模板渲染在頁面上,然而ajax的一個致命缺點就是導致瀏覽器后退按鈕失效,盡管我們可以在頁面上放一個大大的返回按鈕,讓用戶點擊返回來導航,但總是無法避免用戶習慣性的點后退。解決此問題的一個方法是使用hash,監聽hashchange事件來進行視圖切換,另一個方法是用HTML5的history API,通過pushState()記錄操作歷史,監聽popstate事件來進行視圖切換,也有人把這叫pjax技術。基本流程如下:
如此一來,便形成了通過地址欄進行導航的深度鏈接(deeplinking ),也就是我們所需要的路由機制。通過路由機制,一個單頁應用的各個視圖就可以很好的組織起來了。
ngRoute包括的內容
ng的路由機制是靠ngRoute提供的,通過hash和history兩種方式實現了路由,可以檢測瀏覽器是否支持history來靈活調用相應的方式。ng的路由(ngRoute)是一個單獨的模塊,包含以下內容:
- 服務$routeProvider用來定義一個路由表,即地址欄與視圖模板的映射
- 服務$routeParams保存了地址欄中的參數,例如{id : 1, name : 'tom'}
- 服務$route完成路由匹配,并且提供路由相關的屬性訪問及事件,如訪問當前路由對應的controller
- 指令ngView用來在主視圖中指定加載子視圖的區域
以上內容再加上$location服務,我們就可以實現一個單頁面應用了。下面來看一下具體如何使用這些內容。
使用ng的路由機制
第一步:引入文件和依賴
ngRoute模塊包含在一個單獨的文件中,所以第一步需要在頁面上引入這個文件,如下:
<script src="http://code.angularjs.org/1.2.5/angular.min.js"></script> <script src="http://code.angularjs.org/1.2.5/angular-route.min.js"></script>
光引入還不夠,我們還需在模塊聲明中注入對ngRoute的依賴,如下:
var app = angular.module('MyApp', ['ngRoute']);
完成了這些,我們就可以在模板或是controller中使用上面的服務和指令了。下面我們需要定義一個路由表。
第二步:定義路由表
$routeProvider提供了定義路由表的服務,它有兩個核心方法,when(path,route)和otherwise(params),先看一下核心中的核心when(path,route)方法。
when(path,route)方法接收兩個參數,path是一個string類型,表示該條路由規則所匹配的路徑,它將與地址欄的內容($location.path)值進行匹配。如果需要匹配參數,可以在path中使用冒號加名稱的方式,如:path為/show/:name,如果地址欄是/show/tom,那么參數name和所對應的值tom便會被保存在$routeParams中,像這樣:{name : tom}。我們也可以用*進行模糊匹配,如:/show*/:name將匹配/showInfo/tom。
route參數是一個object,用來指定當path匹配后所需的一系列配置項,包括以下內容:
controller //function或string類型。在當前模板上執行的controller函數,生成新的scope controllerAs //string類型,為controller指定別名 template //string或function類型,視圖所用的模板,這部分內容將被ngView引用 templateUrl //string或function類型,當視圖模板為單獨的html文件或是使用了<script type="text/ng-template">定義模板時使用 resolve //指定當前controller所依賴的其他模塊 redirectTo //重定向的地址
最簡單情況,我們定義一個html文件為模板,并初始化一個指定的controller:
function emailRouteConfig($routeProvider){ $routeProvider. when('/show', { controller: ShowController, templateUrl: 'show.html' }). when('/put/:name',{ controller: PutController, templateUrl: 'put.html' }); };
otherwise(params)方法對應路徑匹配不到時的情況,這時候我們可以配置一個redirectTo參數,讓它重定向到404頁面或者是首頁。
第三步:在主視圖模板中指定加載子視圖的位置
我們的單頁面程序都是局部刷新的,那這個“局部”是哪里呢,這就輪到ngView出馬了,只需在模板中簡單的使用此指令,在哪里用,哪里就是“局部”。例如:
<div ng-view></div>
或:
<ng-view></ng-view>
我們的子視圖將會在此處被引入進來。完成這三步后,你的程序的路由就配置好了。
用Route去戰斗吧!
光看了上面的理論部分是不是覺得很抽象、不過癮呢?為了滿足大家的胃口,同時也鞏固我學到的東西,我特地寫了一個demo,模擬我們熟悉的新聞發布系統,使用了上面所介紹的知識。下面由demo華麗麗登場:
大標題和左側部分都是不變的,只是右側的內容在動態加載。并且每次切換不同的視圖,瀏覽器地址欄的內容都相應變化,所以當你點擊后退時,總是能回到上一步的視圖。
由于博客的限制你在這里看不到地址欄變化,點擊http://sandbox.runjs.cn/show/r72hgjwg查看真實運行效果。
查看demo的源碼,點擊這里http://runjs.cn/code/r72hgjwg
關于ng的路由機制就學習到這里的,總結一下,其實路由機制也不難,基本流程就是這樣,但在沒有真正用到項目中前,我也不知道這水到底有多深。本篇博客中的示例我拋棄了jsfiddle.net而用了runjs.cn,原因是jsfiddle簡直慢的像蝸牛,并且angular.js的cdn貌似被墻了,文件一直下載不下來。總體感覺runjs.cn還是挺快的,就是一點不方便,你看源碼還得切出去,木有辦法啦,以后我發現更好的再把runjs給拋棄了~
文章列表