`ui-router` $stateParams vs. $state.params

前端 未结 7 905
隐瞒了意图╮
隐瞒了意图╮ 2020-12-07 08:07

With ui-router, it\'s possible to inject either $state or $stateParams into a controller to get access to parameters in the URL. Howev

相关标签:
7条回答
  • 2020-12-07 08:31

    I have a root state which resolves sth. Passing $state as a resolve parameter won't guarantee the availability for $state.params. But using $stateParams will.

    var rootState = {
        name: 'root',
        url: '/:stubCompanyId',
        abstract: true,
        ...
    };
    
    // case 1:
    rootState.resolve = {
        authInit: ['AuthenticationService', '$state', function (AuthenticationService, $state) {
            console.log('rootState.resolve', $state.params);
            return AuthenticationService.init($state.params);
        }]
    };
    // output:
    // rootState.resolve Object {}
    
    // case 2:
    rootState.resolve = {
        authInit: ['AuthenticationService', '$stateParams', function (AuthenticationService, $stateParams) {
            console.log('rootState.resolve', $stateParams);
            return AuthenticationService.init($stateParams);
        }]
    };
    // output:
    // rootState.resolve Object {stubCompanyId:...}
    

    Using "angular": "~1.4.0", "angular-ui-router": "~0.2.15"

    0 讨论(0)
  • 2020-12-07 08:35

    An interesting observation I made while passing previous state params from one route to another is that $stateParams gets hoisted and overwrites the previous route's state params that were passed with the current state params, but using $state.params doesn't.

    When using $stateParams:

    var stateParams        = {};
    stateParams.nextParams = $stateParams; //{item_id:123}
    stateParams.next       = $state.current.name;
    
    $state.go('app.login', stateParams);
    //$stateParams.nextParams on app.login is now:
    //{next:'app.details', nextParams:{next:'app.details'}}
    

    When using $state.params:

    var stateParams        = {};
    stateParams.nextParams = $state.params; //{item_id:123}
    stateParams.next       = $state.current.name;
    
    $state.go('app.login', stateParams);
    //$stateParams.nextParams on app.login is now:
    //{next:'app.details', nextParams:{item_id:123}}
    
    0 讨论(0)
  • 2020-12-07 08:39

    EDIT: This answer is correct for version 0.2.10. As @Alexander Vasilyev pointed out it doesn't work in version 0.2.14.

    Another reason to use $state.params is when you need to extract query parameters like this:

    $stateProvider.state('a', {
      url: 'path/:id/:anotherParam/?yetAnotherParam',
      controller: 'ACtrl',
    });
    
    module.controller('ACtrl', function($stateParams, $state) {
      $state.params; // has id, anotherParam, and yetAnotherParam
      $stateParams;  // has id and anotherParam
    }
    
    0 讨论(0)
  • 2020-12-07 08:39

    Here in this article is clearly explained: The $state service provides a number of useful methods for manipulating the state as well as pertinent data on the current state. The current state parameters are accessible on the $state service at the params key. The $stateParams service returns this very same object. Hence, the $stateParams service is strictly a convenience service to quickly access the params object on the $state service.

    As such, no controller should ever inject both the $state service and its convenience service, $stateParams. If the $state is being injected just to access the current parameters, the controller should be rewritten to inject $stateParams instead.

    0 讨论(0)
  • 2020-12-07 08:52

    There are many differences between these two. But while working practically I have found that using $state.params better. When you use more and more parameters this might be confusing to maintain in $stateParams. where if we use multiple params which are not URL param $state is very useful

     .state('shopping-request', {
          url: '/shopping-request/{cartId}',
          data: {requireLogin: true},
          params : {role: null},
          views: {
            '': {templateUrl: 'views/templates/main.tpl.html', controller: "ShoppingRequestCtrl"},
            'body@shopping-request': {templateUrl: 'views/shops/shopping-request.html'},
            'footer@shopping-request': {templateUrl: 'views/templates/footer.tpl.html'},
            'header@shopping-request': {templateUrl: 'views/templates/header.tpl.html'}
          }
        })
    
    0 讨论(0)
  • 2020-12-07 08:57

    Another reason to use $state.params is for non-URL based state, which (to my mind) is woefully underdocumented and very powerful.

    I just discovered this while googling about how to pass state without having to expose it in the URL and answered a question elsewhere on SO.

    Basically, it allows this sort of syntax:

    <a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>
    
    0 讨论(0)
提交回复
热议问题