Using $state methods with $stateChangeStart toState and fromState in Angular ui-router

前端 未结 1 363
花落未央
花落未央 2020-12-12 19:18

I\'m writing a handler for $stateChangeStart:

var stateChangeStartHandler = function(e, toState, toParams, fromState, fromParams) {
    if (toSt         


        
相关标签:
1条回答
  • 2020-12-12 19:56

    Suggestion 1

    When you add an object to $stateProvider.state that object is then passed with the state. So you can add additional properties which you can read later on when needed.

    Example route configuration

    $stateProvider
    .state('public', {
        abstract: true,
        module: 'public'
    })
    .state('public.login', {
        url: '/login',
        module: 'public'
    })
    .state('tool', {
        abstract: true,
        module: 'private'
    })
    .state('tool.suggestions', {
        url: '/suggestions',
        module: 'private'
    });
    

    The $stateChangeStart event gives you acces to the toState and fromState objects. These state objects will contain the configuration properties.

    Example check for the custom module property

    $rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) {
        if (toState.module === 'private' && !$cookies.Session) {
            // If logged out and transitioning to a logged in page:
            e.preventDefault();
            $state.go('public.login');
        } else if (toState.module === 'public' && $cookies.Session) {
            // If logged in and transitioning to a logged out page:
            e.preventDefault();
            $state.go('tool.suggestions');
        };
    });
    

    I didn't change the logic of the cookies because I think that is out of scope for your question.

    Suggestion 2

    You can create a Helper to get you this to work more modular.

    Value publicStates

    myApp.value('publicStates', function(){
        return {
          module: 'public',
          routes: [{
            name: 'login', 
            config: { 
              url: '/login'
            }
          }]
        };
    });
    

    Value privateStates

    myApp.value('privateStates', function(){
        return {
          module: 'private',
          routes: [{
            name: 'suggestions', 
            config: { 
              url: '/suggestions'
            }
          }]
        };
    });
    

    The Helper

    myApp.provider('stateshelperConfig', function () {
      this.config = {
        // These are the properties we need to set
        // $stateProvider: undefined
        process: function (stateConfigs){
          var module = stateConfigs.module;
          $stateProvider = this.$stateProvider;
          $stateProvider.state(module, {
            abstract: true,
            module: module
          });
          angular.forEach(stateConfigs, function (route){
            route.config.module = module;
            $stateProvider.state(module + route.name, route.config);
          });
        }
      };
    
      this.$get = function () {
        return {
          config: this.config
        };
      };
    });
    

    Now you can use the helper to add the state configuration to your state configuration.

    myApp.config(['$stateProvider', '$urlRouterProvider', 
        'stateshelperConfigProvider', 'publicStates', 'privateStates',
      function ($stateProvider, $urlRouterProvider, helper, publicStates, privateStates) {
        helper.config.$stateProvider = $stateProvider;
        helper.process(publicStates);
        helper.process(privateStates);
    }]);
    

    This way you can abstract the repeated code, and come up with a more modular solution.

    Note: the code above isn't tested

    0 讨论(0)
提交回复
热议问题