壹 ❀ 引
angularjs除了驚為天人的雙向數據綁定外,路由也是出彩的一筆,通過路由配置,我們能在不發起頁面跳轉的情況下,對當前頁內容進行整體更新,angularjs提供了ngRoute模塊用於路由配置,除此之外,angularUI也提供了uirouter模塊用於解決路由問題,本文將從ngRoute與uirouter兩個模塊出發,分別介紹兩者的路由監聽方法。
貳 ❀ ngRoute路由監聽
ngRoute提供了路由事件用於監聽路由過程中的每個階段,可以為這些不同的路由事件設置監聽器並在路由發生變化時做出響應。先上一個完整的例子,需要引入angularjs與angular-route.js:
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body ng-controller="myCtrl as vm"> <ul> <li><a href="index.html#!/index">index</a></li> <li><a href="index.html#!/login">login</a></li> <li><a href="index.html#!/dashboard">dashboard</a></li> </ul> <div ng-view></div> </body> <script src="node_modules/angular/angular.js"></script> <script src="node_modules/angular-route/angular-route.js"></script> <script src="js/app.js"></script> </html>
angular.module('myApp', ['ngRoute'])
.controller('myCtrl', function ($scope) {
let vm = this
})
.config(['$routeProvider', function ($routeProvider) {
// 在這里定義路由
$routeProvider
.when('/index', {
template: '<div><h2>Route1</h2></div>',
})
.when('/login', {
template: '<div><h2>Route2</h2></div>',
})
.when('/dashboard', {
template: '<div><h2>Route3</h2></div>',
})
.otherwise({
redirectTo: '/index'
});
}])
.run(['$rootScope', '$location', function ($rootScope, $location) {
$rootScope.$on('$routeChangeSuccess', function (evt, current, previous) {
console.log(evt, current, previous);
console.log(1);
});
}]);

1.$routeChangeStart
AngularJS在路由變化之前會執行$routeChangeStart事件。在這一步中,路由服務會開始加載路由變化所需要的所有依賴,並且模板和resolve中的promise也會被resolve。
angular.module('myApp', [])
.run(['$rootScope', '$location', function ($rootScope, $location) {
$rootScope.$on('$routeChangeStart', function (evt, current, previous) {
// do something
// evt 原始的AngularJS evt對象
// current 用戶當前所處的路由
// current 上一個路由(如果當前是第一個路由,則為undefined)。
});
}]);
2. $routeChangeSuccess
AngularJS會在路由的依賴被加載后執行$routeChangeSuccess事件。
angular.module('myApp', [])
.run(['$rootScope', '$location', function ($rootScope, $location) {
$rootScope.$on('$routeChangeSuccess', function (evt, current, previous) {
// do something
// evt 原始的AngularJS evt對象
// current 用戶當前所處的路由
// previous 上一個路由(如果當前是第一個路由,則為undefined)。
});
}]);
3. $routeChangeError
angular.module('myApp', [])
.run(function ($rootScope, $location) {
$rootScope.$on('$routeChangeError', function (current, previous, rejection) {
// do something
// current 當前路由的信息
// previous 上一個路由的信息
// rejection 被拒絕的promise的錯誤信息
});
});
4. $routeUpdate
叄 ❀ uirouter路由監聽
uirouter是由angualrUI提供的三方路由模塊,因此也需要額外下載,並在主模塊中注入路由模塊,需要引入angualrjs,angular-ui-router.js與stateEvents.js,先看一個完整的例子:
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body ng-controller="myCtrl as vm"> <ul> <li><a ui-sref="index">index</a></li> <li><a ui-sref="login">login</a></li> <li><a ui-sref="dashboard">dashboard</a></li> </ul> <div ui-view></div> </body> </body> <script src="modules/angular.js"></script> <script src="modules/@uirouter/angularjs/release/angular-ui-router.js"></script> <script src="modules/@uirouter/angularjs/release/stateEvents.js"></script> <script src="demo.js"></script> </html>
angular.module('myApp', ['ui.router', 'ui.router.state.events'])
.controller('myCtrl', function ($scope) {
let vm = this
})
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
//設置路由初始頁面
$urlRouterProvider.otherwise('orderList');
//路由配置
$stateProvider
.state('index', {
url: '/index',
template: '<div><h2>Route1</h2></div>',
})
.state('login', {
url: '/login',
template: '<div><h2>Route2</h2></div>',
})
.state('dashboard', {
url: '/dashboard',
template: '<div><h2>Route3</h2></div>',
})
}])
.run(['$rootScope', function ($rootScope) {
// 監聽路由開始時觸發
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
//do something
console.log(1);
// event 該事件的基本信息
// toState 當前路由的基本信息,比如路由名稱,url,視圖的控制器,模板路徑等
// toParams 當前路由的參數
// fromState 上一個路由的基本信息,比如路由名稱,url,視圖的控制器,模板路徑等
// fromParams 上一個路由的參數
});
// 路由成功時觸發
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
//do something
// event 該事件的基本信息
// toState 當前路由的基本信息,比如路由名稱,url,視圖的控制器,模板路徑等
// toParams 當前路由的參數
// fromState 上一個路由的基本信息,比如路由名稱,url,視圖的控制器,模板路徑等
// fromParams 上一個路由的參數
});
// 路由錯誤時觸發
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
//do something
// event 該事件的基本信息
// toState 當前路由的基本信息,比如路由名稱,url,視圖的控制器,模板路徑等
// toParams 當前路由的參數
// fromState 上一個路由的基本信息,比如路由名稱,url,視圖的控制器,模板路徑等
// fromParams 上一個路由的參數
// error 錯誤信息
});
}]);

若$stateChangeStart之類的路由事件沒觸發,還是前面說的,得引入stateEvents.js文件,此文件在下載angular-ui-router.js時會同時包含。
肆 ❀ 參考
解決ui-router路由監聽$stateChangeStart、$stateChangeSuccess、$stateChangeError不執行的問題
