Come inviare e recuperare i parametri utilizzando $ state.go toParams e $ stateParams?


123

Sto usando AngularJS v1.2.0-rc.2 con ui-router v0.2.0. Voglio passare lo stato del referrer a un altro stato, quindi uso il toParamsdi in questo $state.gomodo:

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

Secondo i documenti , questo dovrebbe popolare $stateParamsil toStatecontroller, ma lo è undefined. Cosa mi manca?

Ho creato un plunk per dimostrare:

http://plnkr.co/edit/ywEcG1

Risposte:


147

Se si desidera trasmettere uno stato non URL, non è necessario utilizzare urldurante la configurazione del file state. Ho trovato la risposta su un PR e ho cercato di capire meglio.

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

Quindi puoi navigare in questo modo:

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

O:

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

E in HTML così:

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

Questo caso d'uso è completamente scoperto nella documentazione, ma penso che sia un mezzo potente per passare allo stato senza utilizzare URL.


2
NOTA: (su v0.2.10) Se lo stato è uno stato figlio di un genitore che ha un parametro URL, allora quel parametro deve essere incluso paramsnell'array.
ivarni

5
Ho ricevuto un errore che diceva "Parametro richiesto mancante" quando ho elencato i parametri come array nella definizione dello stato. Invece, {referer: true, param2: true, etc: true}
elencali

1
Questo non ha funzionato per me nell'ultima v0.2.13. Forse non era documentato per un motivo.
demisx

1
Negli ultimi tempi, è necessario modificare i parametri per essere un oggetto. so params: {myParam: {value: defaultValue / undefined }}
rbnzdave

2
come posso ottenere i dati nel controller?
Shylendra Madda

47

La soluzione di Nathan Matthews non ha funzionato per me ma è totalmente corretta ma non ha molto senso raggiungere una soluzione alternativa:

Il punto chiave è: il tipo di parametri definiti e toParamas di $ state.go devono essere lo stesso array o oggetto su entrambi i lati della transizione di stato.

Ad esempio, quando definisci un parametro in uno stato come segue, significa che params è un array a causa dell'utilizzo di "[]":

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

Quindi dovresti anche passare aParams come array in questo modo:

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

E puoi accedervi tramite $ stateParams come array in questo modo:

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

La soluzione migliore è usare l'oggetto anziché l'array su entrambi i lati :

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

Ho sostituito [] con {} nella definizione dei parametri. Per passare toParams a $ state.go dovresti anche usare object invece di array:

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

quindi puoi accedervi facilmente tramite $ stateParams:

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

Sicuramente funziona e l'ho usato nel mio progetto. L'hai testato? Fammi sapere il problema, se lo provi.
Reza Rahimi

1
non è un formato oggetto {'index', 'anotherKey'} come può funzionare? L'ho provato. Non ha funzionato.
maxisam

Inserisci il tuo frammento di codice, la versione o qualcosa che possa aiutare a risolvere il problema. Ho usato queste versioni: AngularJS v1.2.26, ui-router v0.2.11, CoffeeScript anche io ho usato la versione di bower di loro.
Reza Rahimi

3
funziona, tuttavia sostituendo params: {'index', 'anotherKey'},con params: {'index' : 'dummy', 'anotherKey' : 'dummy'},altrimenti non è un oggetto javascript valido
ps0604

28

Tutto quello che dovevo fare era aggiungere un parametro alla definizione dello stato dell'URL in questo modo

url: '/toState?referer'

Doh!


L'unico modo in cui posso farlo funzionare con la /toState/:referersintassi è usare $location.path()invece di $state.go().
nshew

Non hai trovato altre soluzioni utilizzando la funzionalità del router ui?
Jason

c'è un modo per farlo funzionare con $ state.go (). Mi ci è voluto del tempo per farlo bene. Vedi il mio esempio qui.
mbokil

Ha funzionato. Tuttavia potrebbe non essere chiaro cosa fare se si desidera passare due parametri; quindi la riga seguente fa il trucco. url: "/ contacts? myParam1 & myParam2"
eduardo92

15

Non sono sicuro che funzionerà con AngularJS v1.2.0-rc.2 con ui-router v0.2.0. Ho testato questa soluzione su AngularJS v1.3.14 con ui-router v0.2.13.

Mi rendo solo conto che non è necessario passare il parametro nell'URL come consigliato da gwhn.

Basta aggiungere i parametri con un valore predefinito nella definizione dello stato. Il tuo stato può ancora avere un valore Url.

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

e aggiungi il parametro a $state.go()

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


Coll ... Mi hai salvato la giornata, uomini! Soluzione semplice e diretta.
Nowdeen

15

Nessuno di questi esempi in questa pagina ha funzionato per me. Questo è quello che ho usato e ha funzionato bene. Alcune soluzioni dicono che non puoi combinare url con $ state.go () ma questo non è vero. La cosa imbarazzante è che devi definire i parametri per l'URL e anche elencare i parametri. Entrambi devono essere presenti. Testato su Angular 1.4.8 e UI Router 0.2.15.

Nello stato aggiungi i tuoi parametri a fine stato e definisci i parametri:

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

Nel tuo controller la tua dichiarazione go sarà simile a questa:

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

Quindi per estrarre i parametri e utilizzarli nel controller del nuovo stato (non dimenticare di passare $ stateParams alla funzione del controller):

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

11

Nel mio caso ho provato con tutte le opzioni fornite qui, ma nessuno funzionava correttamente (angular 1.3.13, ionic 1.0.0, angular-ui-router 0.2.13). La soluzione era:

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

e in state.go:

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

Saluti


Questo ha funzionato bene per me, a condizione che il controller riverisca il parametro con lo stesso nome, quindi $ stateParams.param1 per esempio.
nuander

si @nuander, ho dimenticato di menzionare come accedere a quella variabile, grazie per questo!
Cris R

8

Ho passato molto tempo a combattere con $ state & $ stateParams; di Ionic / Angular;

Per utilizzare $ state.go () e $ stateParams devi avere alcune cose impostate e altri parametri non devono essere presenti.

Nella mia app.config () ho incluso $ stateProvider e al suo interno ho definito diversi stati:

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

La paramschiave è particolarmente importante. Inoltre, nota che NON sono urlpresenti chiavi ... utilizzando stateParams e URL NON si mescolano. Si escludono a vicenda.

Nella chiamata $ state.go (), definiscilo come tale:

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

Le variabili indexe anotherKey$ stateParams verranno popolate SOLO se vengono prima elencate nella paramschiave di definizione $ stateController .

All'interno del controller, includere $ stateParams come illustrato:

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

Le variabili passate dovrebbero essere disponibili!


Il valore può essere un oggetto JSON? Come $ state.go ('view', {'editObj': {val1: 2, val2: 3, val4: 'Hello'}}). Perché questo non funziona per me.
PavanSandeep

6

Provare con reload: true?

Non riuscivo a capire cosa stesse succedendo per il tempo più lungo - è venuto fuori che mi stavo prendendo in giro. Se sei certo che le cose siano scritte correttamente e vorrai usare lo stesso stato, prova reload: true:

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

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

Spero che questo ti faccia risparmiare tempo!


5

Avevo affrontato un problema simile. Ho trovato una soluzione funzionante dopo molte ricerche su Google, prove e test. Ecco la mia soluzione che funzionerebbe per te.

Ho due controller: searchBoxController e stateResultController e un parametro denominato searchQuery da passare da una vista con una casella di ricerca a una vista che mostra i risultati recuperati da un server remoto. Ecco come lo fai:

Di seguito è riportato il controller da cui si richiama la vista successiva utilizzando $state.go()

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

Di seguito è riportato lo stato che verrebbe chiamato quando $state.go()viene eseguito:

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

E infine, il controller associato allo app.searchResultsstato:

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

1
Questo ha funzionato per me ed era esattamente ciò di cui avevo bisogno, poiché non volevo passare il parametro nell'URL ma avevo bisogno della proprietà url nella dichiarazione di stato.
Ernani

3

E nel mio caso di uno stato genitore / figlio. tutti i parametri dichiarati nello stato figlio devono essere conosciuti dallo stato genitore

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

2

La soluzione alla quale siamo arrivati ​​per avere uno stato che richiedeva 2 parametri stava cambiando:

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

per

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

1

La tua definizione di seguito in router.js

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

Il controller deve aggiungere $ stateParams.

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

È possibile inviare un oggetto tramite parametro come segue.

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

1

Stavo cercando di navigare dalla pagina 1 alla pagina 2 e ho dovuto passare anche alcuni dati.

Nel mio router.js , ho aggiunto il nome e l' età dei parametri :

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

In Pagina1 , onClick del pulsante successivo:

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

In Page2 , potrei accedere a quei parametri:

$stateParams.name
$stateParams.age

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.