Wie sende und rufe ich Parameter mit $ state.go toParams und $ stateParams ab?

123

Ich verwende AngularJS v1.2.0-rc.2 mit ui-router v0.2.0. Ich möchte den Referrer - Zustand in einen anderen Zustand übergeben , damit ich die Verwendung toParamsvon in $state.goetwa so:

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

Laut den Dokumenten sollte dies die $stateParamsauf dem toStateController füllen, aber es ist undefined. Was vermisse ich?

Ich habe ein Plunk erstellt, um zu demonstrieren:

http://plnkr.co/edit/ywEcG1

gwhn
quelle

Antworten:

147

Wenn Sie den Nicht-URL-Status übergeben möchten, dürfen Sie ihn urlbeim Einrichten nicht verwenden state. Ich fand die Antwort in einer PR und machte ein paar Affen, um besser zu verstehen.

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

Dann können Sie wie folgt dorthin navigieren:

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

Oder:

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

Und in HTML also:

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

Dieser Anwendungsfall wird in der Dokumentation vollständig aufgedeckt, aber ich denke, er ist ein leistungsstarkes Mittel, um den Status ohne Verwendung von URLs zu ändern.

braun
quelle
2
HINWEIS: (in Version 0.2.10) Wenn der Status ein untergeordneter Status eines übergeordneten Elements mit einem URL-Parameter ist, muss dieser Parameter in das paramsArray aufgenommen werden.
ivarni
5
Ich habe die Fehlermeldung "Fehlender erforderlicher Parameter" erhalten, als ich die Parameter als Array in der Statusdefinition aufgelistet habe. Listen Sie sie stattdessen als Hash auf{referer: true, param2: true, etc: true}
Dave Ceddia
1
Dies hat in der neuesten Version 0.2.13 bei mir nicht funktioniert. Vielleicht war es aus einem bestimmten Grund nicht dokumentiert.
Demisx
1
Spätestens müssen Sie die Parameter ändern, um ein Objekt zu sein. also params: {myParam: {value: defaultValue / undefined }}
rbnzdave
2
Wie kann ich die Daten in der Steuerung erhalten?
Shylendra Madda
47

Die Lösung von Nathan Matthews hat bei mir nicht funktioniert, ist aber völlig korrekt, aber es macht wenig Sinn, eine Problemumgehung zu erreichen:

Der entscheidende Punkt ist: Der Typ der definierten Parameter und toParamas von $ state.go sollte auf beiden Seiten des Zustandsübergangs dasselbe Array oder Objekt sein.

Wenn Sie beispielsweise einen Parameter in einem Status wie folgt definieren, bedeutet dies, dass der Parameter aufgrund der Verwendung von "[]" ein Array ist:

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

Daher sollten Sie auch Params als Array wie folgt übergeben:

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

Und Sie können über $ stateParams als Array wie folgt darauf zugreifen:

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

Eine bessere Lösung ist die Verwendung von Objekt anstelle von Array auf beiden Seiten :

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

Ich habe [] in der Parameterdefinition durch {} ersetzt. Um toParams an $ state.go zu übergeben, sollten Sie auch object anstelle von array verwenden:

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

dann können Sie einfach über $ stateParams darauf zugreifen:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams.index;
    var anotherKey = $stateParams.anotherKey;
});
Reza Rahimi
quelle
Auf jeden Fall funktioniert es und ich habe es in meinem Projekt verwendet. Hast du es getestet? Lassen Sie mich das Problem wissen, wenn Sie es testen.
Reza Rahimi
1
Es ist kein Objektformat {'index', 'anotherKey'}. Wie kann das funktionieren? Ich habe es versucht. Es hat nicht funktioniert.
Maxisam
Geben Sie Ihr Code-Snippet, Ihre Version oder etwas ein, das zur Lösung des Problems beitragen kann. Ich habe diese Versionen verwendet: AngularJS v1.2.26, UI-Router v0.2.11, CoffeeScript. Ich habe auch die Version von Bower verwendet.
Reza Rahimi
3
dies funktioniert, ersetzen aber params: {'index', 'anotherKey'},mit params: {'index' : 'dummy', 'anotherKey' : 'dummy'},ansonsten ist es kein gültiges Javascript - Objekt
ps0604
28

Alles, was ich tun musste, war einen Parameter wie folgt zur URL-Statusdefinition hinzuzufügen

url: '/toState?referer'

Doh!

gwhn
quelle
Die einzige Möglichkeit, dies mit /toState/:refererSyntax zum Laufen zu bringen, ist die Verwendung von $location.path()anstelle von $state.go().
Nshew
Sie haben keine andere Lösung mit der Funktionalität des UI-Routers gefunden?
Jason
Es gibt eine Möglichkeit, dies mit $ state.go () zum Laufen zu bringen. Ich habe einige Zeit gebraucht, um es richtig zu machen. Siehe mein Beispiel hier.
mbokil
Es funktionierte. Es ist jedoch möglicherweise nicht klar, was passiert, wenn Sie zwei Parameter übergeben möchten. Die folgende Zeile macht also den Trick. URL: "/ Kontakte? myParam1 & myParam2"
eduardo92
15

Ich bin mir nicht sicher, ob es mit AngularJS v1.2.0-rc.2 mit ui-router v0.2.0 funktioniert. Ich habe diese Lösung auf AngularJS v1.3.14 mit ui-router v0.2.13 getestet.

Mir ist nur klar, dass es nicht notwendig ist, den Parameter in der URL zu übergeben, wie von gwhn empfohlen.

Fügen Sie einfach Ihre Parameter mit einem Standardwert in Ihrer Statusdefinition hinzu. Ihr Bundesstaat kann weiterhin einen URL-Wert haben.

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

und fügen Sie den Parameter hinzu $state.go()

$state.go('state1',{new_param: "Going places!"});
Phyxius
quelle
Wie hier dokumentiert: Verwenden von Parametern ohne Angabe in
Status-
Coll ... Du hast meine Tagesmänner gerettet! Einfache und direkte Lösung.
Nowdeen
15

Keines dieser Beispiele auf dieser Seite hat bei mir funktioniert. Das habe ich benutzt und es hat gut funktioniert. Einige Lösungen sagten, dass Sie URL nicht mit $ state.go () kombinieren können, aber dies ist nicht wahr. Das Unangenehme ist, dass Sie die Parameter für die URL definieren und auch die Parameter auflisten müssen. Beides muss vorhanden sein. Getestet auf Angular 1.4.8 und UI Router 0.2.15.

Im Zustand Ihre params zu Ende Zustand hinzufügen und definieren Sie die params:

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

In Ihrem Controller sieht Ihre go-Anweisung folgendermaßen aus:

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

Ziehen Sie dann die Parameter heraus und verwenden Sie sie im Controller Ihres neuen Status (vergessen Sie nicht, $ stateParams an Ihre Controller-Funktion zu übergeben):

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

In meinem Fall habe ich es mit allen hier angegebenen Optionen versucht, aber niemand hat richtig funktioniert (Angular 1.3.13, Ionic 1.0.0, Angular-UI-Router 0.2.13). Die Lösung war:

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

und im state.go:

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

Prost

Cris R.
quelle
Dies funktionierte gut für mich, vorausgesetzt, der Controller verehrt den gleichnamigen Parameter, also beispielsweise $ stateParams.param1.
Nuander
ja @nuander, ich habe vergessen zu erwähnen, wie man auf diese Variable zugreift, danke dafür!
Cris R
8

Ich habe viel Zeit damit verbracht, mit Ionic / Angulars $ state & $ stateParams;

Um $ state.go () und $ stateParams verwenden zu können, müssen bestimmte Dinge eingerichtet sein und andere Parameter dürfen nicht vorhanden sein.

In meiner app.config () habe ich $ stateProvider eingefügt und darin mehrere Zustände definiert:

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

Der paramsSchlüssel ist besonders wichtig. urlBeachten Sie auch, dass KEINE Schlüssel vorhanden sind. Wenn Sie stateParams verwenden und URLs NICHT mischen. Sie schließen sich gegenseitig aus.

Definieren Sie den Aufruf von $ state.go () als solchen:

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

Die Variablen indexund anotherKey$ stateParams werden NUR ausgefüllt, wenn sie zuerst im paramsDefinitionsschlüssel $ stateController aufgeführt werden .

Fügen Sie im Controller $ stateParams wie folgt ein:

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

Die übergebenen Variablen sollten verfügbar sein!

Nathan Matthews
quelle
Kann der Wert ein JSON-Objekt sein? Wie $ state.go ('view', {'editObj': {val1: 2, val2: 3, val4: 'Hello'}}). Weil das bei mir nicht funktioniert.
PavanSandeep
6

Versuchen Sie es mit reload: true?

Konnte nicht herausfinden, was am längsten vor sich ging - es stellte sich heraus, dass ich mich selbst betrogen hatte. Wenn Sie sicher sind, dass die Dinge richtig geschrieben sind und Sie denselben Status verwenden möchten, versuchen Sie Folgendes reload: true:

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

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

Hoffe das spart dir Zeit!

Cody
quelle
5

Ich hatte ein ähnliches Problem. Nach vielem googeln und Ausprobieren hatte ich eine funktionierende Lösung. Hier ist meine Lösung, die für Sie funktionieren würde.

Ich habe zwei Controller - searchBoxController und stateResultController und einen Parameter namens searchQuery , der von einer Ansicht mit einem Suchfeld an eine Ansicht übergeben werden soll, in der die von einem Remote-Server abgerufenen Ergebnisse werden. Das ist wie man es macht:

Unten sehen Sie den Controller, von dem aus Sie die nächste Ansicht mit aufrufen $state.go()

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

Unten ist der Zustand, der aufgerufen werden würde, wenn die $state.go() ausgeführt wird:

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

Und schließlich der dem app.searchResultsStaat zugeordnete Controller :

.controller('stateResultController', function ($scope, $state, $stateParams, $http) {
        $scope.searchQueryInput = $stateParams.searchQuery;
    });
Azharullah Shariff
quelle
1
Dies funktionierte für mich und war genau das, was ich brauchte, da ich den Parameter nicht in der URL übergeben wollte, sondern die Eigenschaft url in der Statusdeklaration benötigte.
Ernani
3

Und in meinem Fall eines Eltern / Kind-Staates. Alle im untergeordneten Status deklarierten Parameter müssen dem übergeordneten Status bekannt sein

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

Die Lösung für einen Zustand mit zwei Parametern war die Änderung:

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

zu

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

Sie definieren Folgendes in router.js

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

Ihr Controller muss $ stateParams hinzufügen.

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

Sie können ein Objekt wie folgt per Parameter senden.

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

Ich habe versucht, von Seite 1 nach Seite 2 zu navigieren, und ich musste auch einige Daten übergeben.

In meiner router.js habe ich den Namen und das Alter der Parameter hinzugefügt :

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

In Seite1 , onClick der nächsten Taste:

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

In Seite 2 konnte ich auf folgende Parameter zugreifen:

$stateParams.name
$stateParams.age
Praveesh P.
quelle