AngularJS路由系列(5)-- UI-Router的路由约束、Resolve属性、路由附加数据、路由进入退出事件

本系列探寻AngularJS的路由机制,在WebStorm下开发。主要包括:

● UI-Router约束路由参数
● UI-Router的Resolve属性
● UI-Router给路由附加数据
● UI-Router的onEnter和onExit事件

AngularJS路由系列包括:

1、AngularJS路由系列(1)--基本路由配置
2、AngularJS路由系列(2)--刷新、查看路由,路由事件和URL格式,获取路由参数,路由的Resolve
3、AngularJS路由系列(3)-- UI-Router初体验
4、AngularJS路由系列(4)-- UI-Router的$state服务、路由事件、获取路由参数
5、AngularJS路由系列(5)-- UI-Router的路由约束、Resolve属性、路由附加数据、路由进入退出事件
6、AngularJS路由系列(6)-- UI-Router的嵌套State

项目文件结构

node_modules/
public/
.....app/
..........bower_components/
...............toastr/
....................toastr.min.css
....................toastr.min.js
...............jquery/
....................dist/
.........................jquery.min.js
...............angular/
....................angular.min.js
...............angular-ui-router/
....................release/
.........................angular-ui-router.min.js
...............angular-route/
.........................angular-route.min.js
..........controllers/
...............HomeController.js
...............AllSchoolsController.js
...............AllClassroomsController.js
...............AllActivityiesController.js
...............ClassroomController.js
...............ClassroomSummaryController.js
...............ClassroomMessageController.js
..........css/
...............bootstrap.cerulean.min.css
..........filters/
...............activityMonthFilter.js
..........services/
...............dataServices.js
...............notifier.js
..........templates/
...............home.html
...............allSchools.html
...............allClassrooms.html
...............allActivities.html
...............classroom.html
...............classroomDetail.html
...............classroom_parent.html
..........app.js
.....index.html
.....favicon.ico
server/
.....data/
.....routes/
.....views/
.....helpers.js
package.json
server.js

UI-Router约束路由参数

■ app.js, 约束参数

(function(){
    var app = angular.module(‘app‘,[‘ui.router‘]);

    app.config([‘$logProvider‘, ‘$stateProvider‘, function($logProvider, $stateProvider){
        $logProvider.debugEnabled(true);

        $stateProvider
            .state(‘home‘,{
                url: ‘/‘,
                templateUrl: ‘/app/templates/home.html‘,
                controller: ‘HomeController‘, //也可以写成HomeController as home
                controllerAs: ‘home‘
            })
            .state(‘schools‘,{
                url: ‘/schools‘,
                controller: ‘AllSchoolController‘,
                controllerAs: ‘schools‘,
                templateUrl: ‘/app/templates/allSchools.thml‘
            })
            .state(‘classrooms‘,{
                url:‘/classrooms‘,
                controller: ‘AllClassroomsController‘,
                controllerAs: ‘classrooms‘,
                templateUrl: ‘/app/tempates/allClassrooms.html‘
            })
            .state(‘activities‘, {
                url: ‘/activities‘,
                controller: ‘AllActivitiesController‘,
                controllerAs: ‘activities‘,
                templateUrl: ‘/app/templates/allActivities.html‘
            })
            .state(‘classroom_summary‘, {
                url: ‘/classrooms/:id‘,
                templateUrl: ‘/app/templates/classroom.html‘,
                controller: ‘ClassroomController‘,
                controllerAs: ‘classroom‘
            })
            .state(‘classroom_detail‘,{
                url: ‘/classrooms/{id: [0-9]}/detail/{month}‘,
                templateUrl: ‘/app/templates/classroomDetail.html‘,
                controller: ‘ClassroomController‘,
                controllerAs: ‘classroom‘
            })
    }]);

    app.run([‘$rootScope‘, ‘$log‘, function($rootScope, $log){
        $rootScope.$on(‘$stateChangeSuccess‘, function(event, toState, toParams, fromState, fromParams){
            $log.debug(‘successfully changed states‘) ;

            $log.debug(‘event‘, event);
            $log.debug(‘toState‘, toState);
            $log.debug(‘toParams‘, toParams);
            $log.debug(‘fromState‘, fromState);
            $log.debug(‘fromParams‘, fromParams);
        });

        $rootScope.$on(‘$stateNotFound‘, function(event, unfoundState, fromState, fromParams){
            $log.error(‘The request state was not found: ‘ + unfoundState);
        });

        $rootScope.$on(‘$stateChangeError‘, function(event, toState, toParams, fromState, fromParams, error){
            $log.error(‘An error occurred while changing states: ‘ + error);

            $log.debug(‘event‘, event);
            $log.debug(‘toState‘, toState);
            $log.debug(‘toParams‘, toParams);
            $log.debug(‘fromState‘, fromState);
            $log.debug(‘fromParams‘, fromParams);
        });
    }]);
}());

url: ‘/classrooms/{id: [0-9]}/detail/{month}‘这个就对id这个路由参数进行了约束。

■ app.js, 路由参数不符合约束的解决办法

UI-Router为我们提供了$urlRouteProvider服务。

(function(){
    var app = angular.module(‘app‘,[‘ui.router‘]);

    app.config([‘$logProvider‘, ‘$stateProvider‘, ‘$urlRouteProvider‘, function($logProvider, $stateProvider, $urlRouteProvider){
        $logProvider.debugEnabled(true);

        //解决路由异常的办法在这里
        $urlRouteProvider.otherwise(‘/‘);

        $stateProvider
            .state(‘home‘,{
                url: ‘/‘,
                templateUrl: ‘/app/templates/home.html‘,
                controller: ‘HomeController‘, //也可以写成HomeController as home
                controllerAs: ‘home‘
            })
            .state(‘schools‘,{
                url: ‘/schools‘,
                controller: ‘AllSchoolController‘,
                controllerAs: ‘schools‘,
                templateUrl: ‘/app/templates/allSchools.thml‘
            })
            .state(‘classrooms‘,{
                url:‘/classrooms‘,
                controller: ‘AllClassroomsController‘,
                controllerAs: ‘classrooms‘,
                templateUrl: ‘/app/tempates/allClassrooms.html‘
            })
            .state(‘activities‘, {
                url: ‘/activities‘,
                controller: ‘AllActivitiesController‘,
                controllerAs: ‘activities‘,
                templateUrl: ‘/app/templates/allActivities.html‘
            })
            .state(‘classroom_summary‘, {
                url: ‘/classrooms/:id‘,
                templateUrl: ‘/app/templates/classroom.html‘,
                controller: ‘ClassroomController‘,
                controllerAs: ‘classroom‘
            })
            .state(‘classroom_detail‘,{
                url: ‘/classrooms/{id: [0-9]}/detail/{month}‘,
                templateUrl: ‘/app/templates/classroomDetail.html‘,
                controller: ‘ClassroomController‘,
                controllerAs: ‘classroom‘
            })
    }]);

    app.run([‘$rootScope‘, ‘$log‘, function($rootScope, $log){
        $rootScope.$on(‘$stateChangeSuccess‘, function(event, toState, toParams, fromState, fromParams){
            $log.debug(‘successfully changed states‘) ;

            $log.debug(‘event‘, event);
            $log.debug(‘toState‘, toState);
            $log.debug(‘toParams‘, toParams);
            $log.debug(‘fromState‘, fromState);
            $log.debug(‘fromParams‘, fromParams);
        });

        $rootScope.$on(‘$stateNotFound‘, function(event, unfoundState, fromState, fromParams){
            $log.error(‘The request state was not found: ‘ + unfoundState);
        });

        $rootScope.$on(‘$stateChangeError‘, function(event, toState, toParams, fromState, fromParams, error){
            $log.error(‘An error occurred while changing states: ‘ + error);

            $log.debug(‘event‘, event);
            $log.debug(‘toState‘, toState);
            $log.debug(‘toParams‘, toParams);
            $log.debug(‘fromState‘, fromState);
            $log.debug(‘fromParams‘, fromParams);
        });
    }]);
}());

■ UI-Router的params属性设置路由参数

(function(){
    var app = angular.module(‘app‘,[‘ui.router‘]);

    app.config([‘$logProvider‘, ‘$stateProvider‘, ‘$urlRouteProvider‘, function($logProvider, $stateProvider, $urlRouteProvider){
        $logProvider.debugEnabled(true);

        //解决路由异常的办法在这里
        $urlRouteProvider.otherwise(‘/‘);

        $stateProvider
            .state(‘home‘,{
                url: ‘/‘,
                templateUrl: ‘/app/templates/home.html‘,
                controller: ‘HomeController‘, //也可以写成HomeController as home
                controllerAs: ‘home‘
            })
            .state(‘schools‘,{
                url: ‘/schools‘,
                controller: ‘AllSchoolController‘,
                controllerAs: ‘schools‘,
                templateUrl: ‘/app/templates/allSchools.thml‘
            })
            .state(‘classrooms‘,{
                url:‘/classrooms‘,
                controller: ‘AllClassroomsController‘,
                controllerAs: ‘classrooms‘,
                templateUrl: ‘/app/tempates/allClassrooms.html‘
            })
            .state(‘activities‘, {
                url: ‘/activities‘,
                controller: ‘AllActivitiesController‘,
                controllerAs: ‘activities‘,
                templateUrl: ‘/app/templates/allActivities.html‘
            })
            .state(‘classroom_summary‘, {
                url: ‘/classrooms/:id‘,
                templateUrl: ‘/app/templates/classroom.html‘,
                controller: ‘ClassroomController‘,
                controllerAs: ‘classroom‘
            })
            .state(‘classroom_detail‘,{
                url: ‘/classrooms/{id: [0-9]}/detail/{month}‘,
                templateUrl: ‘/app/templates/classroomDetail.html‘,
                controller: ‘ClassroomController‘,
                controllerAs: ‘classroom‘,
                params: {
                    classroomMessage: { value: ‘Learning is fun!‘}
                }
            })
    }]);

    app.run([‘$rootScope‘, ‘$log‘, function($rootScope, $log){
        $rootScope.$on(‘$stateChangeSuccess‘, function(event, toState, toParams, fromState, fromParams){
            $log.debug(‘successfully changed states‘) ;

            $log.debug(‘event‘, event);
            $log.debug(‘toState‘, toState);
            $log.debug(‘toParams‘, toParams);
            $log.debug(‘fromState‘, fromState);
            $log.debug(‘fromParams‘, fromParams);
        });

        $rootScope.$on(‘$stateNotFound‘, function(event, unfoundState, fromState, fromParams){
            $log.error(‘The request state was not found: ‘ + unfoundState);
        });

        $rootScope.$on(‘$stateChangeError‘, function(event, toState, toParams, fromState, fromParams, error){
            $log.error(‘An error occurred while changing states: ‘ + error);

            $log.debug(‘event‘, event);
            $log.debug(‘toState‘, toState);
            $log.debug(‘toParams‘, toParams);
            $log.debug(‘fromState‘, fromState);
            $log.debug(‘fromParams‘, fromParams);
        });
    }]);
}());

■ ClassroomController.js, 接受更多的路由参数

(function(){
    angular.module(‘app‘)
        .controller(‘ClassroomController‘,[‘dataService‘, ‘notifier‘, ‘$stateParams‘, ClassroomController]);

    function ClassroomController(dataService, notifier, $stateParams){
        var vm = this;

        vm.month = $stateParams.month;

        //接受param设置的参数
        vm.message = $stateParams.classroomMessage;

        dataService.getClassroom($stateParams.id)
            .then(function(classroom){
                vm.currentClassroom = classroom;

                if($stateParams.month){
                    if(classroom.activities.length > 0){
                        vm.timePeriod = dataService.getMonthName($stateParams.month);
                    } else {
                        vm.timePeriod = ‘No activities this month‘;
                    }
                }
                else{
                    vm.timePeriod = ‘All activities‘;
                }
            })
            .catch(showError);

        function showError(message){
            notifier.error(message);
        }

    }
}());

■ classroomDetal.html

{{classroom.message}}

UI-Router的Resolve属性

■ resolve 属性

.state(‘activities‘,{
    url: ‘/activities‘,
    controller: ‘AllAcivitiesController‘,
    controllerAs: ‘activities‘,
    templateUrl: ‘/app/templates/allActivities.html‘,
    resolve: {
        activities: function(dataService){
            return dataService.getAllActiviites();
        }
    }
})

● 可以被注入到controller中去
● 返回一个object对象,对象的属性自定义,属性值是一个返回promise的函数
● promises必须被resolve,在变化发生之前

■ app.js, 添加resolve属性

.state(‘activities‘,{
    url: ‘/activities‘,
    controller: ‘AlLActivitiesController‘,
    controllerAs: ‘activities‘,
    templateUrl: ‘/app/templates/allActivities.html‘,
    resolve: {
        activities: function(dataService){
            return dataService.getAllActivites();
        }
    }
})

■ AllActivitiesController.js,从resolve中获取数据

(function(){
    angular.module(‘app‘)
        .controller(‘AllActivitiesController‘,[‘dataService‘,‘notifier‘,‘$state‘,‘activites‘, AllActivitiesController]);

    function AllActivitiesController(dataService, notifier, $state, activities){
        var vm = this;

        vm.selectedMonth = 1;
        vm.allActivities = activities;

        vm.search = function(){
            $state.go(‘classroom_detail‘,{id:vm.selectedClassroom.id, month: vm.selectedMonth});
        }

        dataService.getAllClassrooms()
            .then(function(classroom){
                vm.allClassrooms = classrooms;
                vm.selectedClassroom = classrooms[0];
            })
            .catch(showError);

        function showError(message){
            notifier.error(message);
        }
    }
}());

当点击Activites的时候,数据已经在controller,不需要重新获取,大大减少了页面加载时间。

UI-Router给路由附加数据

■ 给states附加数据

.state(‘activities‘,{
    url: ‘/activities‘,
    controller: ‘AllActivitesController‘,
    templateUlr: ‘/app/templates/allActivities.html‘,
    data: {
        name: ‘MyActivity‘,
        desc: ‘Fun!‘
    }
})

● data中定义的属性是任意的
● 能被子state继承

■ app.js, 添加附加数据

.state(‘activities‘,{
    url: ‘/activities‘,
    controller: ‘AlLActivitiesController‘,
    controllerAs: ‘activities‘,
    templateUrl: ‘/app/templates/allActivities.html‘,
    resolve: {
        activities: function(dataService){
            return dataService.getAllActivites();
        }
    },
    data: {
        name: ‘My Activity‘,
        desc: ‘Func!‘
    },
    foo: {
        myFoo: ‘bar‘
    }
})

■ AllActivitiesController.js,从resolve中获取数据

(function(){
    angular.module(‘app‘)
        .controller(‘AllActivitiesController‘,[‘dataService‘,‘notifier‘,‘$state‘,‘activites‘,‘$log‘, AllActivitiesController]);

    function AllActivitiesController(dataService, notifier, $state, activities, $log){
        var vm = this;

        vm.selectedMonth = 1;
        vm.allActivities = activities;

        $log.debug($state.current.data);
        $log.debug($state.current.foo);

        vm.search = function(){
            $state.go(‘classroom_detail‘,{id:vm.selectedClassroom.id, month: vm.selectedMonth});
        }

        dataService.getAllClassrooms()
            .then(function(classroom){
                vm.allClassrooms = classrooms;
                vm.selectedClassroom = classrooms[0];
            })
            .catch(showError);

        function showError(message){
            notifier.error(message);
        }
    }
}());

UI-Router的onEnter和onExit事件

.state(‘classroom‘,{
    url:‘/clsssrooms‘,
    controller:‘AllClssroomsController‘,
    controllerAs: ‘classrooms‘,
    templateUrl: ‘/app/tempaltes/allClassrooms.html‘,
    onEnter: function($log){
        $log.debug(‘Entering the classrooms state‘);
    },
    onExit: function($log){
        $log.debug(‘Existing the classrooms state‘);
    }
})

未完待续~~

时间: 2024-12-15 01:52:10

AngularJS路由系列(5)-- UI-Router的路由约束、Resolve属性、路由附加数据、路由进入退出事件的相关文章

[转]AngularJS 使用 UI Router 实现表单向导

本文转自:http://www.oschina.net/translate/angularjs-multi-step-form-using-ui-router 今天我们将使用AngularJs和伟大的UI Router以及Angular ngAnimate module创建一个带动画的多步表单.这项技术可以用在你想要简化用户操作的大表单上. 我们看到这项技术已经应用在了许多的网页上.比如购物车,注册表单,入职流程以及许多多步表单,让用户更容易在线填写表单. 下面我们将构建它: 使用UI Rout

ngRoute 和 ui.router 的使用方法和区别

在单页面应用中要把各个分散的视图给组织起来是通过路由机制来实现的.本文主要对 AngularJS 原生的 ngRoute 路由模块和第三方路由模块 ui.router 的用法进行简单介绍,并做一个对比. ngRoute 使用方法 1) 引入 angular-route lib 无论是 ngRoute 还是 ui.router ,作为框架额外的附加功能,都必须以 模块依赖 的形式被引入. 1 <script src="lib/angular-route.js"></sc

AngularJS路由系列(6)-- UI-Router的嵌套State

本系列探寻AngularJS的路由机制,在WebStorm下开发.本篇主要涉及UI-Route的嵌套State. 假设一个主视图上有两个部分视图,部分视图1和部分视图2,主视图对应着一个state,两个部分视图分别对应state1和state2,那state与state1和state2形成了嵌套关系. AngularJS路由系列包括: 1.AngularJS路由系列(1)--基本路由配置2.AngularJS路由系列(2)--刷新.查看路由,路由事件和URL格式,获取路由参数,路由的Resolv

AngularJS路由系列(3)-- UI-Router初体验

本系列探寻AngularJS的路由机制,在WebStorm下开发. AngularJS路由系列包括: 1.AngularJS路由系列(1)--基本路由配置2.AngularJS路由系列(2)--刷新.查看路由,路由事件和URL格式,获取路由参数,路由的Resolve3.AngularJS路由系列(3)-- UI-Router初体验4.AngularJS路由系列(4)-- UI-Router的$state服务.路由事件.获取路由参数5.AngularJS路由系列(5)-- UI-Router的路由

AngularJS路由系列(2)--刷新、查看路由,路由事件和URL格式,获取路由参数,路由的Resolve

本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● 刷新路由● 查看当前路由以及所有路由● 路由触发事件● 获取路由参数 ● 路由的resolve属性● 路由URL格式 项目文件结构 node_modules/ public/.....app/..........bower_components/...............toastr/....................toastr.min.css....................toastr.min

Vue系列:Vue Router 路由梳理

Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌.包含的功能有: 嵌套的路由/视图表 模块化的.基于组件的路由配置 路由参数.查询.通配符 基于 Vue.js 过渡系统的视图过渡效果 细粒度的导航控制 带有自动激活的 CSS class 的链接 HTML5 历史模式或 hash 模式,在 IE9 中自动降级 自定义的滚动条行为 1.动态路由 动态路由,可以将某种模式匹配到的所有路由,并全都映射到同个组件. (通俗点,比如根

Angularjs中UI Router全攻略

摘自:Angularjs中UI Router全攻略 温馨提示:想要了解 angular-ui-router的同学,从上往下读一遍,能带随着coding那就更好了,保证你对angular-ui-router基本全部掌握. 如何引用依赖angular-ui-router angular.module('app',["ui.router"]) .config(function($stateProvider){ $stateProvider.state(stateName, stateCofi

Angularjs中UI Router用法小记录

今天自己参考已有的项目代码学习了下UI Router的用法,写了个小demo,验证了下自己的想法,现把使用情况记录一下. 1.入口文件index.html,引入项目所需的js文件,标注ng-app,创建ui-view元素,为后面的嵌套做容器准备. <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8">

Vue.js路由管理器 Vue Router

起步 HTML <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <h1>Hello App!</h1> <p>