web-dev-qa-db-fra.com

Comment envoyer et récupérer des paramètres en utilisant $ state.go toParams et $ stateParams?

J'utilise AngularJS v1.2.0-rc.2 avec ui-router v0.2.0. Je veux passer l'état référent à un autre état, donc j'utilise la variable toParams de $state.go comme suit:

$state.go('toState', {referer: $state.current.name});

Selon docs , cela devrait renseigner le $stateParams sur le contrôleur toState, mais c'est undefined. Qu'est-ce que je rate?

J'ai créé un dossier pour démontrer: 

http://plnkr.co/edit/ywEcG1

120
gwhn

Tout ce que je devais faire était d’ajouter un paramètre à la définition de l’état de l’URL comme

url: '/toState?referer'

Doh!

27
gwhn

Si vous souhaitez transmettre un état non-URL, vous ne devez pas utiliser url lors de la configuration de votre state. J'ai trouvé la réponse sur un PR et j'ai fait du singe pour mieux comprendre.

$stateProvider.state('toState', {
  templateUrl:'wokka.html',
  controller:'stateController',
  params: {
    'referer': 'some default', 
    'param2': 'some default', 
    'etc': 'some default'
  }
});

Ensuite, vous pouvez y accéder comme suit:

$state.go('toState', { 'referer':'jimbob', 'param2':37, 'etc':'bluebell' });

Ou:

var result = { referer:'jimbob', param2:37, etc:'bluebell' };
$state.go('toState', result);

Et en HTML ainsi:

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

Ce cas d'utilisation est complètement découvert dans la documentation, mais je pense que c'est un moyen puissant de passer d'un état à un autre sans utiliser d'URL.

143
bbrown

La solution de Nathan Matthews n'a pas fonctionné pour moi, mais elle est tout à fait correcte, mais il est inutile de trouver une solution de contournement:

Le point clé est le suivant: Le type des paramètres définis et toParamas de $ state.go doivent être identiques, au même tableau ou au même objet, des deux côtés de la transition d'état.  

Par exemple, lorsque vous définissez un paramètre dans un état comme suit, vous signifiez que param est un tableau en raison de l'utilisation de "[]":

$stateProvider
.state('home', {
    templateUrl: 'home',
    controller:  'homeController'
})
.state('view', {
    templateUrl: 'overview',
    params:      ['index', 'anotherKey'],
    controller:  'overviewController'
})

Alors aussi, vous devriez passer toParams comme un tableau comme ceci:

params = { 'index': 123, 'anotherKey': 'This is a test' }
paramsArr = (val for key, val of params)
$state.go('view', paramsArr)

Et vous pouvez y accéder via $ stateParams en tant que tableau comme ceci:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams[0];
    var anotherKey = $stateParams[1];
});

La meilleure solution consiste à utiliser un objet au lieu d'un tableau des deux côtés :

$stateProvider
.state('home', {
    templateUrl: 'home',
    controller:  'homeController'
})
.state('view', {
    templateUrl: 'overview',
    params:      {'index': null, 'anotherKey': null},
    controller:  'overviewController'
})

J'ai remplacé [] par {} dans la définition de params. Pour passer toParams à $ state.go, vous devez également utiliser object au lieu de array:

$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' })

vous pourrez ensuite y accéder facilement via $ stateParams:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams.index;
    var anotherKey = $stateParams.anotherKey;
});
46
Reza Rahimi

Pas sûr que cela fonctionne avec AngularJS v1.2.0-rc.2 avec ui-router v0.2.0 . J'ai testé cette solution sur AngularJS v1.3.14 avec ui-router v0.2.13.

Je viens de réaliser que ce n’est pas nécessaire de passer le paramètre dans l’URL comme le recommande gwhn.

Ajoutez simplement vos paramètres avec une valeur par défaut dans votre définition d'état . Votre état peut toujours avoir une valeur Url.

$stateProvider.state('state1', {
    url : '/url',
    templateUrl : "new.html",
    controller : 'TestController',
    params: {new_param: null}
});

et ajoutez le paramètre à $state.go()

$state.go('state1',{new_param: "Going places!"});
15
Phyxius

Aucun de ces exemples sur cette page n'a fonctionné pour moi. C'est ce que j'ai utilisé et cela a bien fonctionné. Certaines solutions disent que vous ne pouvez pas combiner url avec $ state.go (), mais ce n'est pas vrai. Le problème, c’est que vous devez définir les paramètres pour l’url et les lister. Les deux doivent être présents. Testé sur Angular 1.4.8 et UI Router 0.2.15.

Dans state, ajoutez vos paramètres à la fin de l'état et définissez-les:

url: 'view?index&anotherKey',
params: {'index': null, 'anotherKey': null}

Dans votre controller, votre déclaration go ressemblera à ceci:

$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' });

Ensuite, pour sortir les paramètres et les utiliser dans le contrôleur de votre nouvel état (n'oubliez pas de passer $ stateParams à la fonction de votre contrôleur):

var index = $stateParams.index;
var anotherKey = $stateParams.anotherKey;
console.log(anotherKey); //it works!
14
mbokil

Dans mon cas, j'ai essayé avec toutes les options données ici, mais personne ne fonctionnait correctement (angular 1.3.13, ionic 1.0.0, angular-ui-router 0.2.13). La solution était:

.state('tab.friends', {
      url: '/friends/:param1/:param2',
      views: {
        'tab-friends': {
          templateUrl: 'templates/tab-friends.html',
          controller: 'FriendsCtrl'
        }
      }
    })

et dans le state.go:

$state.go('tab.friends', {param1 : val1, param2 : val2});

À votre santé

10
Cris R

J'ai passé beaucoup de temps à me battre avec les $ state & $ stateParams;

Pour utiliser $ state.go () et $ stateParams, vous devez configurer certaines choses et aucun autre paramètre ne doit être présent.

Dans app.config (), j'ai inclus $ stateProvider et défini plusieurs états:

$stateProvider
    .state('home', {
        templateUrl: 'home',
        controller:  'homeController'
    })
    .state('view', {
        templateUrl: 'overview',
        params:      ['index', 'anotherKey'],
        controller:  'overviewController'
    })

La clé params est particulièrement importante. De plus, notez qu'il n'y a AUCUNE clé url présente ... en utilisant stateParams et les URL ne se mélangent PAS. Ils s'excluent mutuellement.

Dans l'appel $ state.go (), définissez-le comme tel:

$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' })

Les variables index et anotherKey $ $ StateParams seront UNIQUEMENT renseignées si elles sont d'abord répertoriées dans la clé de définition $ stateController params.

Dans le contrôleur, incluez $ stateParams comme illustré:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams.index;
    var anotherKey = $stateParams.anotherKey;
});

Les variables passées doivent être disponibles!

8
Nathan Matthews

Essayez avec reload: true?

Je ne pouvais pas comprendre ce qui se passait depuis le plus longtemps - il s'avère que je me leurrais. Si vous êtes certain que les choses sont écrites correctement et que vous utiliserez le même état, essayez reload: true:

.state('status.item', {
    url: '/:id',
    views: {...}
}

$state.go('status.item', { id: $scope.id }, { reload: true });

J'espère que cela vous fait gagner du temps!

5
Cody

J'avais rencontré un problème similaire. Je me suis retrouvé avec une solution de travail après beaucoup de recherches sur Google, d’essais et de tests. Voici ma solution qui fonctionnerait pour vous.

J'ai deux contrôleurs - searchBoxController et stateResultController et un paramètre nommé searchQuery à transmettre depuis une vue comportant un champ de recherche vers une vue affichant les résultats extraits d'un serveur distant. Voici comment vous le faites:

Ci-dessous, le contrôleur à partir duquel vous appelez la vue suivante à l'aide de $state.go().

.controller('searchBoxController', function ($scope, $state) {
        $scope.doSearch = function(){
            var searchInputRaw = $scope.searchQueryInput;
            $state.go('app.searchResults', { searchQuery: searchInput });
        }
    })

Vous trouverez ci-dessous l'état qui serait appelé lorsque la $state.go() sera exécutée:

.state('app.searchResults', 
            {
                url: '/searchResults',
                views:
                {
                    'menuContent': { templateUrl: 'templates/searchResult.html', controller: 'stateResultController' }
                },
                params: 
                {
                    'searchQuery': ''
                }
            })

Et enfin, le contrôleur associé à l'état app.searchResults:

.controller('stateResultController', function ($scope, $state, $stateParams, $http) {
        $scope.searchQueryInput = $stateParams.searchQuery;
    });
4
Azharullah Shariff

Et dans mon cas d'un état parent/enfant. tous les paramètres déclarés dans l'état enfant doivent être connus de l'état parent

        .state('full', {
            url: '/full',
            templateUrl: 'js/content/templates/FullReadView.html',
            params: { opmlFeed:null, source:null },
            controller: 'FullReadCtrl'
        })
        .state('full.readFeed', {
            url: '/readFeed',
            views: {
                'full': {
                    templateUrl: 'js/content/templates/ReadFeedView.html',
                    params: { opmlFeed:null, source:null },
                    controller: 'ReadFeedCtrl'
                }
            }
        })
3
zinking

La solution à laquelle nous sommes arrivés à avoir un état qui prenait 2 paramètres changeait

.state('somestate', {
  url: '/somestate',
  views: {...}
}

à

.state('somestate', {
  url: '/somestate?id=:&sub=:',
  views: {...}
}
2
Seth Caldwell

S'il s'agit d'un paramètre de requête que vous souhaitez transmettre, procédez comme suit: /toState?referer=current_user

alors vous devez décrire votre état comme ceci:

$stateProvider.state('toState', {
  url:'toState?referer',
  views:{'...'}
});

source: https://github.com/angular-ui/ui-router/wiki/URL-Routing#query-parameters

0
lgx

J'essayais de naviguer de la page 1 à la page 2 et je devais également transmettre des données.

Dans mon routeur.js , j'ai ajouté les paramètres name et age:

.state('page2', {
          url: '/vehicle/:source',
          params: {name: null, age: null},
.................

Dans Page1 , onClick du bouton suivant: 

$state.go("page2", {name: 'Ron', age: '20'});

Dans Page2 , je pourrais accéder à ces paramètres:

$stateParams.name
$stateParams.age
0
Praveesh P

Votre définition suivante dans router.js

$stateProvider.state('users', {
    url: '/users',
    controller: 'UsersCtrl',
    params: {
        obj: null
    }
})

Votre contrôleur doit ajouter $ stateParams.

function UserCtrl($stateParams) {
    console.log($stateParams);
}

Vous pouvez envoyer un objet par paramètre comme suit.

$state.go('users', {obj:yourObj});
0
MahmutKarali