就我現在的認識,路由($route)這個東西(也許可以加上$location)可以說是ng最重要的東西了。因為angular目前最重要的作用就是做單頁面webApp,而路由這個東西是能做到頁面跳轉的關鍵。
1.單頁面webApp
為什么叫單頁面webApp?因為它是單頁面的。。。。額。。。關鍵在於我們看到的不少webApp是多頁面的啊,可以從一頁跳到另一頁。嗯,看起來是這樣,不過實際上這幾頁實際還是一個頁面,因為它們是一次性加載進來的,至於為啥會有跳轉效果呢?嗯,有點兒像選項卡,嗯。其實現原理在html5之前是通過hashbang,H5是History。這篇文章主要討論的是hashbang。為什么要用#呢?當然我們可以直接多頁面,就跟做網站一樣。但是這么做最大的問題是:每次切換都需要重新加載頁面。我們可以接受進入一個app的時候多花幾秒加載,而在使用App的時候切換頁面的時候多等個一兩秒就會給用戶一種這app好卡的感覺。
另外webApp另外一個好處就是可以減輕服務器壓力,后台只管給數據。嗯,其實我不是很懂這一點。。以后再補充吧。
2.路由(ng-route)
那么怎么把單頁面webapp(SPA)做成多頁面的樣子呢?就是怎么來管理這些頁面呢?就要靠路由了。
來個案例,這是一個信息管理系統,管用戶注冊,注銷,用戶列表,用戶詳情之類的東西。
<!DOCTYPE html> <html lang="en" ng-controller="userlist"> <head> <meta charset="UTF-8"> </head> <body> <div> <table> <tr ng-repeat="x in data" ng-click="detail($index)"> <td>{{ x.name }}:{{ x.password }}<a href="#ddd/{{$index}}">查看詳情</a></td> </tr> </table> </div> </body> </html>
html我就粘一部分,這一部分是顯示用戶列表的,點擊對應用戶需要顯示它們的對應信息。為什么選這一部分,是因為這里需要做地址傳參。
再看看對應的管路由跳轉的js代碼
m1.config(["$routeProvider",function($routeProvider){ $routeProvider.when("/aaa",{ templateUrl:"register.html", controller:"register" }).when("/bbb",{ templateUrl:"cancel.html", controller:"cancel" }).when("/ccc",{ templateUrl:"userlist.html", controller:"userlist" }) .when("/ddd/:index",{ templateUrl:"detail.html", controller:"detail" }) .otherwise({redirectTo:"/aaa"}); }])
其中
.when("/ddd/:index",{ templateUrl:"detail.html", controller:"detail" })
對應着用戶列表頁面。
首先,m1.config(["$routeProvider",function($routeProvider)])是注入模塊的過程,因為ng-route是一個獨立於ng之外的模塊,是一個獨立的js文件。
然后,when函數的參數,第一個是url地址(后面接的:index待會講地址傳參的時候再說)。templateUrl是轉到的頁面地址(內容少的話可以用template),controller寫跳轉到的頁面的控制器。
跳轉之后的頁面url大概是長這樣的:http://localhost:63342/%E8%B7%AF%E7%94%B1/index.html#/ddd
最后說說地址傳參的問題,在詳細頁中,我們只需要顯示對應的一個人的信息,就是說不管你點誰的詳情顯示的一個頁面,但是你需要告訴詳情頁點擊的究竟是哪個按鈕,我該渲染哪個。代碼里的:index代表着你點擊的用戶的列表索引(就是你點擊的是第幾個用戶),傳索引是因為用戶信息數據是用數組存的。在列表頁中,這個變量叫index或者啥的都無所謂,因為這只是占了個坑,代表這里傳的值可以用這個變量來取(當然這個名字在跳轉過去的詳情頁是有用的)。再看看對應的html怎么寫的
<tr ng-repeat="x in data" ng-click="detail($index)"> <td>{{ x.name }}:{{ x.password }}<a href="#ddd/{{$index}}">查看詳情</a></td> </tr>
這里的$index對應的就是點擊的這個tr在這個表格中的索引,確切的來說是x是data中的第幾項。index就對應了{{$index}}
如果加上了參數的話,跳轉頁的url長這樣http://localhost:63342/%E8%B7%AF%E7%94%B1/index.html#/ddd/0
后面多加的這個0就是傳的參數了,想要在跳轉頁取到這個參數,可以用$routeParams
m1.controller("detail",["$scope","$routeParams",function($scope,$routeParams){ $scope.index=$routeParams.index; }]);
就是說,這里$routeParams.index中的index對應着在when函數中寫的那個。
說句題外話,之前我不用地址傳參的時候,實現”多頁面"通信的方式是在$rootScope里寫個屬性存上要傳的數據,畢竟ng只有一個$rootScope。雖然沒想出這么做有什么不妥,但是內心當中總覺得好別扭。。
下一節說說自定義指令。