angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题
壹 ❀ 引
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不执行的问题