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.