• 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');
        }
    })

    未完待续~~

  • 相关阅读:
    Redis安装与配置
    Mysql主从复制
    MySQL的基本使用
    如何理解 python 里面的 for 循环
    我在创业公司的 “云原生” 之旅
    linux 安装 kafka
    数据库性能优化
    Shell 中各种括号的作用
    DNS 配置实例-正反解析-主从同步-分离解析
    DHCP 中继转发配置(ensp 实现)
  • 原文地址:https://www.cnblogs.com/darrenji/p/4982517.html
Copyright © 2020-2023  润新知