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

Met ui-routeris het mogelijk om $stateof $stateParamsin een controller te injecteren om toegang te krijgen tot parameters in de URL . Echter, toegang tot parameters via $stateParamsstelt alleen parameters bloot die behoren tot de status die wordt beheerd door de controller die er toegang toe heeft, en zijn bovenliggende statussen, terwijl $state.paramsalle parameters heeft, inclusief die in alle onderliggende staten.

Gezien de volgende code, als we de URL http://path/1/paramA/paramBrechtstreeks laden, gaat het als volgt wanneer de controllers worden geladen:

$stateProvider.state('a', {
     url: 'path/:id/:anotherParam/',
     controller: 'ACtrl',
  });
$stateProvider.state('a.b', {
     url: '/:yetAnotherParam',
     controller: 'ABCtrl',
  });
module.controller('ACtrl', function($stateParams, $state) {
   $state.params; // has id, anotherParam, and yetAnotherParam
   $stateParams;  // has id and anotherParam
}
module.controller('ABCtrl', function($stateParams, $state) {
   $state.params; // has id, anotherParam, and yetAnotherParam
   $stateParams;  // has id, anotherParam, and yetAnotherParam
}

De vraag is, waarom het verschil? En zijn er richtlijnen voor beste praktijken over wanneer en waarom u een van beide zou moeten gebruiken of vermijden?


Antwoord 1, autoriteit 100%

De documentatie herhaalt uw bevindingen hier: https://github.com/ hoekige-ui/ui-router/wiki/URL-Routing#stateparams-service

Als mijn geheugen goed is, $stateParamswerd later geïntroduceerd dan de originele $state.params, en lijkt een eenvoudige hulpinjector te zijn om te voorkomen dat je voortdurend $state.params.

Ik betwijfel of er richtlijnen voor best practices zijn, maar de context wint het voor mij. Als je gewoon toegang wilt tot de parameters die in de url zijn ontvangen, gebruik dan $stateParams. Als je iets ingewikkelders wilt weten over de staat zelf, gebruik dan $state.


Antwoord 2, autoriteit 28%

Een andere reden om $state.paramste gebruiken is voor niet-URL-gebaseerde status, die (naar mijn mening) jammerlijk ondergedocumenteerd en zeer krachtig is.

Ik ontdekte dit net toen ik googelde over hoe je de status kunt doorgeven zonder het in de URL te hoeven tonen en beantwoordde ergens anders een vraagop SO.

In principe staat het dit soort syntaxis toe:

<a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>

Antwoord 3, autoriteit 21%

EDIT: Dit antwoord is correct voor versie 0.2.10. Zoals @Alexander Vasilyev opmerkte, werkt het niet in versie 0.2.14.

Een andere reden om $state.paramste gebruiken, is wanneer u queryparameters als volgt moet extraheren:

$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
}

Antwoord 4, autoriteit 6%

Er zijn veel verschillen tussen deze twee. Maar terwijl ik praktisch werkte, heb ik ontdekt dat het beter is om $state.paramste gebruiken. Als je steeds meer parameters gebruikt, kan dit verwarrend zijn om te onderhouden in $stateParams. waar als we meerdere params gebruiken die geen URL zijn, param $stateerg handig is

.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'}
      }
    })

Antwoord 5, autoriteit 4%

Ik heb een root-status die sth oplost. Het doorgeven van $stateals een resolutieparameter garandeert niet de beschikbaarheid voor $state.params. Maar het gebruik van $stateParamswel.

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:...}

Met “hoekig”: “~1.4.0”, “hoekig-ui-router”: “~0.2.15”


Antwoord 6, autoriteit 3%

Een interessante observatie die ik heb gemaakt bij het doorgeven van eerdere statusparameters van de ene route naar de andere, is dat $stateParams wordt gehesen en de statusparameters van de vorige route overschrijft die zijn doorgegeven met de huidige statusparameters, maar met behulp van $state.params niet.

Bij gebruik van $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'}}

Bij gebruik van $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}}

Antwoord 7

Hierin dit artikel wordt duidelijk uitgelegd: De service $statebiedt een aantal handige methoden om de status te manipuleren, evenals relevante gegevens over de huidige status. De huidige statusparameters zijn toegankelijk via de service $statemet de params-toets. De service $stateParamsretourneert ditzelfde object. Daarom is de service $stateParamsstrikt een gemaksservice om snel toegang te krijgen tot het params-object op de service $state.

Als zodanig mag geen enkele controller ooit zowel de service $stateals de gemaksservice $stateParamsinjecteren. Als de $statealleen wordt geïnjecteerd om toegang te krijgen tot de huidige parameters, moet de controller worden herschreven om in plaats daarvan $stateParamste injecteren.

Other episodes