web-dev-qa-db-fra.com

angular ui-router: obtenir $ state info de toState en résolution

Mise à jour : cela devrait être possible dans angular-ui-router à partir de 1.0.0alpha0. Voir les notes de version https://github.com/angular-ui/ui-router/releases/tag/1.0.0alpha et le problème https://github.com/angular -ui/ui-router/issues/1018 J'ai créé.

Je souhaite accéder au nom de l'État et aux autres attributs auxquels l'application accède en utilisant angular ui-router lorsque vous travaillez sur la résolution.

La raison: je veux charger certaines données utilisateur (y compris leurs droits d'accès) de manière asynchrone avant d'autoriser l'application à accéder à cette page.

Actuellement, cela n'est pas possible car l'injection de $ state dans la résolution pointe vers l'état vers lequel vous vous éloignez, pas vers celui vers lequel vous naviguez.

Je sais que je peux:

  • obtenir le toState ailleurs avec $ rootScope ('$ stateChangeStart') et l'enregistrer dans mon service de paramètres par exemple. Mais je pense que c'est un peu désordonné.
  • coder en dur l'état dans la résolution, mais je ne veux pas réutiliser ma résolution pour toutes les pages

J'ai également créé un problème sur le github ui-router (S'il vous plaît + 1 si vous êtes intéressé!): https://github.com/angular-ui/ui-router/issues/1018

Voici mon code jusqu'à présent. Toute aide appréciée!

.config(function($stateProvider) {

    $stateProvider.state('somePage', {
        // ..
        resolve: {
            userData: function($stateParams, $state, Settings) {
                return Settings.getUserData() // load user data asynchronously
                    .then(function (userData) {
                        console.log($stateParams);
                        console.log($state);
                        // Problem: $state still points to the state you're navigating away from
                    });
            }
        }
    });
});
46
Jonathan Grupp

Mise à jour pour Ui-Router 1.x

$provide.decorator('$state', ($delegate, $transitions) => {
    $transitions.onStart({}, (trans) => {
      $delegate.toParams = trans.params()
      $delegate.next = trans.to().name
    })
    return $delegate
  })

Ui-Router 0.x

Vous pouvez toujours décorer $state avec les propriétés next et toParams:

angular.config(function($provide) {
  $provide.decorator('$state', function($delegate, $rootScope) {
    $rootScope.$on('$stateChangeStart', function(event, state, params) {
      $delegate.next = state;
      $delegate.toParams = params;
    });
    return $delegate;
  });
});

Et utiliser comme tel:

.state('myState', {
    url: '/something/{id}',
    resolve: {
        oneThing: function($state) {
            console.log($state.toParams, $state.next);
        }
    }
});
56
TaylorMac

J'ai donc découvert la réponse à cela moi-même. Si votre code se comporte comme le mien, l'objet $ stateParams est correctement injecté, mais $ state est un objet d'état vide (ou ancien).

Ce qui a fonctionné pour moi, c'était de référencer this dans la fonction de résolution:

.state('myState', {
    url: '/something/{id}',
    templateUrl: '/myTemplate.html',
    controller: function() {},
    resolve: {
        oneThing: function($stateParams) {
            console.log($stateParams); // comes through fine
            var state = this;
            console.log(state); // will give you a "raw" state object
        }
    }
})

Le premier journal renverra ce que vous attendez. Le deuxième journal renverra un objet d'état "brut" (faute d'un meilleur terme). Ainsi, par exemple, pour obtenir le nom de l'État, vous pouvez accéder à, this.self.name.

Je me rends compte que ce n'est pas préféré ... ce serait beaucoup plus agréable si $state (ou un autre objet standardisé) pourrait nous fournir ces informations à la résolution, mais c'est le mieux que j'ai pu trouver.

J'espère que cela pourra aider...

31
Nathan Rutman

this.toString () vous donnera le nom de l'état

1
Hari Haran