angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题

 壹 ❀ 引

angularjs除了惊为天人的双向数据绑定外,路由也是出彩的一笔,通过路由配置,我们能在不发起页面跳转的情况下,对当前页内容进行整体更新,angularjs提供了ngRoute模块用于路由配置,除此之外,angularUI也提供了uirouter模块用于解决路由问题,本文将从ngRoute与uirouter两个模块出发,分别介绍两者的路由监听方法。

 贰 ❀ ngRoute路由监听

ngRoute提供了路由事件用于监听路由过程中的每个阶段,可以为这些不同的路由事件设置监听器并在路由发生变化时做出响应。先上一个完整的例子,需要引入angularjs与angular-route.js:

angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题
<!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>
View Code angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题
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);
        });
    }]);
View Code

angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题

 

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

AngularJS会在任何一个promise被拒绝或者失败时执行$routeChangeError事件。
angular.module('myApp', [])
    .run(function ($rootScope, $location) {
        $rootScope.$on('$routeChangeError', function (current, previous, rejection) {
            // do something
            // current 当前路由的信息
            // previous 上一个路由的信息
            // rejection 被拒绝的promise的错误信息
        });
    });

4. $routeUpdate

AngularJS在reloadOnSearch属性被设置为false的情况下, 重新使用某个控制器的实例时,会执行$routeUpdate事件。

 叁 ❀ uirouter路由监听

uirouter是由angualrUI提供的三方路由模块,因此也需要额外下载,并在主模块中注入路由模块,需要引入angualrjs,angular-ui-router.js与stateEvents.js,先看一个完整的例子:

angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题
<!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>
View Code angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题
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 错误信息
        });
    }]);
View Code

angularjs路由监听,uirouter感知路由变化,解决uirouter路由监听不生效的问题

若$stateChangeStart之类的路由事件没触发,还是前面说的,得引入stateEvents.js文件,此文件在下载angular-ui-router.js时会同时包含。

 肆 ❀ 参考

 解决ui-router路由监听$stateChangeStart、$stateChangeSuccess、$stateChangeError不执行的问题

angularJS路由详解

上一篇:angular directive 自定义指令--属性方式简单学习


下一篇:JavaScript"模拟事件"的注意要点