AngularJS 路由機制是由ngRoute模塊提供,它容許咱們將視圖分解成佈局和模板視圖,根據url變化動態的將模板視圖加載到佈局中,從而實現單頁面應用的頁面跳轉功能。html
AngularJS 路由容許咱們經過不一樣的 URL 訪問不一樣的內容。web
經過 AngularJS 能夠實現多視圖的單頁Web應用(single page web application,SPA)。promise
一般咱們的URL形式爲 http://cnblogs.com/first/page,但在單頁Web應用中 AngularJS 經過 # + 標記 實現,例如:瀏覽器
http://cnblogs.com/#/first
http://cnblogs.com/#/second
http://cnblogs.com/#/third
當咱們點擊以上的任意一個連接時,向服務端請的地址都是同樣的 (http:/cnblogs.com/)。 由於 # 號以後的內容在向服務端請求時會被瀏覽器忽略掉。 因此咱們就須要在客戶端實現 # 號後面內容的功能實現。 AngularJS 路由 就經過 # + 標記 幫助咱們區分不一樣的邏輯頁面並將不一樣的頁面綁定到對應的控制器上。服務器
01app
<script src="angular-route.min.js"></script> var app = angular.module("myApp",['ngRoute']);
之因此要建立佈局模板,是爲了告訴AngularJS應該將佈局渲染到何處。經過ng-view指令,咱們能夠精確的指定模板視圖在DOM中的渲染位置。編輯器
<div ng-app="myApp"> <a ng-href="#/bq1">標籤1</a> <a ng-href="#/bq2">標籤2</a> <a ng-href="#/bq3">標籤3</a> <a ng-href="#/bq4">標籤4</a> <div ng-view></div> </div>
myBq1.htmlide
<p>這是標籤1</p>
myBq2.html函數
<p>這是標籤2</p>
myBq3.html佈局
<p>這是標籤3</p>
myBq4.html
<p>這是標籤4</p>
app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/',{templateUrl:"home.html"}) .when('/music',{templateUrl:"myMusic.html"}) .when('/movie',{templateUrl:"myMovie.html"}) .when('/novel',{templateUrl:"myNovel.html"}) .otherwise({redirectTo:'/'}); }]);
02
若是沒有參數,返回當前路徑,即#號後的內容;也能夠傳入字符串,將當前路徑修改成字符串的內容,並觸發路由變化。
假設當前url:http://localhost:63342/RouteDemo/index.html#/
//返回'/'
$location.path();
//將當前url修改成:http://localhost:63342/RouteDemo/index.html#/music
$locaiton.path('/music');
//返回'/music'
$locaiton.path();
when方法可以接收兩個參數,第一個參數是路由路徑,這個路徑會與$location.path()的值進行匹配,若是沒有任何一個when方法匹配到,那麼將會執行otherwise方法。第二個參數是配置對象,它的六個屬性分別是controller,template,templateUrl,resolve,redirectTo,reloadOnSearch。
//每次路徑變爲/music觸發路由變化時都會執行一次控制器中的內容 app.config(['$routeProvider',function($routeProvide) { $routeProvide.when('/music'{templateUrl:"myMusic.html",controller:"myController"}) }]); app.controller('myController',function($scope) { console.log("123"); });
只有當resolve對象裏全部promise對象執行完畢後纔會注入到控制器,此時纔會發生路由變化,所以能夠解決頁面閃爍問題(加載頁面後才獲取到數據去更新視圖)。咱們來看看對比,下面這個例子控制器注入的a是自定義的myService服務,注入的b則是從服務器端獲取到的數據。
test.html代碼以下。
<p>我是測試界面 {{ name }}</p> <div ng-repeat="name in list">{{ name }}</div>
index.html代碼以下。
<body ng-app="myApp"> <div ng-app="myApp"> <a ng-href="#/test">測試</a> <div ng-view></div> </div> <script> var app = angular.module("myApp",['ngRoute']); app.value("myService","張三"); app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/test',{templateUrl:"test.html", controller:function($scope,a,b) { $scope.name = "你好"+a; $scope.list = b.data; }, resolve:{ a:"myService", b:function($http,$timeout) { var promise = $timeout(function() { return $http.get("http://localhost:3000/person"); },3000); return promise; } }}); }]); </script> </body>
若是直接在控制器而不是resolve中請求,則index.html代碼以下。
<body ng-app="myApp"> <div ng-app="myApp"> <a ng-href="#/test">測試</a> <div ng-view></div> </div> <script> var app = angular.module("myApp",['ngRoute']); app.value("myService","張三"); app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/test',{templateUrl:"test.html", controller:function($scope,$http,$timeout,a) { $scope.name = "你好"+a; var promise = $timeout(function() { return $http.get("http://localhost:3000/person"); },3000); promise.then(function(response) { $scope.list = response.data; }); }, resolve:{ a:"myService" }}); }]); </script> </body>
二者效果以下,能夠看到寫在控制器中的代碼不只須要本身處理邏輯(控制器不推薦寫太複雜的邏輯)從promise的success function中取得repsonse參數,並且頁面加載不一致,服務器獲取的數據在得到後才加載,而在resolve中寫,只有等promise執行完畢後纔會跳轉,而後同步加載整個頁面。
- redirectTo
值是一個字符串或一個函數,該屬性寫在otherwise中,表明着在when中找不到相應路徑時的重定向。若是是字符串,路徑會被替換成該值,若是是函數,它有三個參數,第一個是當前路徑的路由參數,第二個是當前路徑,第三個當前Url的查詢串,路徑會被替換成該函數的返回值,替換後都會觸發路由變化。
- reloadOnSearch
值是一個布爾值,爲true的時候$location.search()發生變化時就會從新加載路由,location.search是從當前URL的?號開始(包括?號)的字符串。
咱們能夠在路由參數的前面加上:號,AngularJS會把它解析出來並傳遞給$routeParams。
下面的例子中咱們將123456傳給value,AngularJS把其解析出來,在$routeParams中添加一個名爲value的鍵,值爲123456,咱們能夠將該服務注入到控制器中使用。
test.html代碼以下。
<p>我是測試界面 {{ display }}</p>
<body ng-app="myApp"> <div ng-app="myApp"> <a ng-href="#/test/123456">測試</a> <div ng-view></div> </div> <script> var app = angular.module("myApp",['ngRoute']); app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/test/:value',{templateUrl:"test.html", controller:function($scope,$routeParams) { $scope.display = $routeParams.value; }}); }]); </script> </body>
$route服務在路由過程當中的每一個階段都會觸發不一樣的事件,能夠爲這些事件設置監聽器並作出響應。路由事件都是系統自動從$rootScope廣播下去的,咱們最好的作法是在$rootScope中監聽,而最佳設置的地方就是run方法,能夠保證不會漏掉任何路由變化。
下面是四種不一樣的路由事件。
$routeUpdate 在reloadOnSearch屬性設置爲false的狀況下,從新使用某個控制器的實例會廣播該事件。