走進AngularJs(八) ng的路由機制

呂大豹發表於2013-12-18

  在談路由機制前有必要先提一下現在比較流行的單頁面應用,就是所謂的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給拋棄了~

相關文章