Ich habe einen übergeordneten Zustand, in dem sich zwei Kinder befinden, in dem ich einen Zustand basierend auf URL
anzeigen werde.
Von diesen beiden states
muss man Parameter wie param1
und param2
verwenden. Ich habe die Option params
von ui-router in der Zustandsdefinition.
Zustand
$stateProvider.state('tabs.account', {
url: '/account',
views: {
'[email protected]': {
templateUrl: 'account.html',
controller: function($scope, $stateParams) {
//This params are internally used to make ajax and show some data.
$scope.param1 = $stateParams.param1;
$scope.param2 = $stateParams.param2;
},
}
},
params: {
param1: { value: null }, //this are optional param
param2: { value: null } //because they are not used in url
}
});
Wenn Sie sich meine Route ansehen, wird die Option params nicht wirklich in URL
eingeführt. Deshalb erwäge ich sie als optional.
Schau dir plunkr an, ich habe zwei Tabs angezeigt Account & Survey,
textarea
einige Daten hinzu. Klicken Sie auf Gehe zu Konto, um diese Werte an textarea
an den anderen Account -Regler zu übergeben, indem Sie ui-sref="tabs.account({param1: thing1, param2: thing2})"
auf dem Anker ausführen
Nun sehen Sie die param1
& param2
-Werte in HTML, die dem Bereich von $stateParams
zugewiesen wurden.
param
nicht null
erhält.Ich glaube, Sie haben das bekommen, was ich fragen wollte, warum der optionale Parameterwert nicht gespeichert wurde. wie sie ein Teil des Staates waren.
Ich weiß, dass ich dieses Problem durch zwei Lösungen lösen kann.
url: '/account/:param1/:param2',
(aber ich würde das nicht vorziehen)Ich habe schon eckige-ui-routers sticky states
ausprobiert, aber das scheint für mich nicht zu funktionieren. Was ist der bessere Weg dazu?
Gibt es eine Möglichkeit, wie ich meinen Use Case zum Laufen bringen kann? Alle Ideen würden uns freuen.
Github Issue Link hier
Ich würde die params
-Definition in den übergeordneten Zustand verschieben, um die optionalen Zustandsparameter zwischen Ihren beiden untergeordneten Zuständen zu teilen.
Die untergeordneten Staaten erben die $stateParams
von deinen Eltern, als solche ist keine wirkliche "Problemumgehung" erforderlich.
Einfach spritzen $stateParams
wie in Ihren untergeordneten Controllern üblich, und Sie haben vollen Zugriff auf die Parameter, die weitergegeben werden. Wenn Sie die Parameter nicht in einem bestimmten untergeordneten Zustand verwenden möchten, vermeiden Sie es einfach, sie zu injizieren.
Das funktioniert mit;
$stateProvider
.state('parent', {
params: { p1: null, p2: null }
})
.state('parent.childOne', {
url: '/one',
controller: function ($stateParams) {
console.log($stateParams); // { p1: null, p2: null }
}
})
.state('parent.childTwo', {
url: '/two',
controller: function ($stateParams) {
console.log($stateParams); // { p1: null, p2: null }
}
})
Wenn Sie zu irgendeinem Zeitpunkt löschen die Parameter während der Fahrt innerhalb des Zustandsbaums von parent
löschen möchten, müssten Sie dies manuell tun.
Das wäre die only wirkliche Einschränkung, die ich bei Verwendung dieser Lösung sehen kann.
Ich stelle fest, dass manuelles Löschen in dem Fall, in dem Sie anwesend sind, möglicherweise nicht wünschenswert ist, aber Sie haben sich nicht aktiv dagegen ausgesprochen, weshalb ich der Meinung bin, dass der Vorschlag sinnvoll ist.
Eine workaround - Lösung besteht darin, die Zustandsparameter zwischenzuspeichern und sie beim Eintritt in den tabs.account
-Zustand bedingt zu laden. Mit der UI-Router-Statuskonfiguration können Sie tatsächlich einen onEnter
-Rückruf für diese Arten von Situationen bereitstellen, bei denen "beim Eintreten des Status etwas unternommen wird".
Hier ist die grundlegende Logik, die localStorage als Cache verwendet, wobei der Plunker hier funktioniert:
tabs.account
-Status eingeben, prüfen Sie, ob die Statusparameter ________ vorhanden sind.$stateParams
.Hier ein Beispiel-Code-Snippet als Referenz (aus dem Plunker):
$stateProvider.state('tabs.account', {
...
onEnter: ['$stateParams', '$window', function($stateParams, $window) {
if($stateParams.param1) {
$window.localStorage.setItem('tabs.account.param1', $stateParams.param1);
} else {
$stateParams.param1 = $window.localStorage.getItem('tabs.account.param1');
}
if($stateParams.param2) {
$window.localStorage.setItem('tabs.account.param2', $stateParams.param2);
} else {
$stateParams.param2 = $window.localStorage.getItem('tabs.account.param2');
}
}],
...
}
Ein Vorbehalt ist, dass Ihre Parameter auf unbestimmte Zeit bestehen bleiben (z. B. zwischen Aktualisierungen und Sitzungen). Um dies zu umgehen, können Sie den Cache beim Laden der Anwendung wie in app.run
löschen.
Eine letzte Anmerkung ist, dass ich im Plunker direkt auf den lokalen Speicher zugreife (über den Angular $window
-Dienst). Möglicherweise möchten Sie ein AngularJS-Modul verwenden - ich habe angle-local-storage in der Produktion verwendet.
Ich glaube, dass das, was Sie erreichen möchten, nicht möglich ist, ohne eine der beiden Lösungen zu verwenden, die Sie bereitgestellt haben.
Die Zurück-Schaltfläche des Browsers speichert nur den URL-Verlauf. Er hat keine Ahnung von den internen Zuständen des UI-Routers und erzwingt nur die Änderung der URL.
Das Erzwingen der URL zum Ändern löst einen internen UI-Router aus, aber leider wird der UI-Router die Änderung der URL genauso sehen, als ob jemand die URL manuell geändert hätte.
Der Ui-Router löst eine neue Routenänderung an der Route aus, auf die die URL verweist. Das heißt, er weiß nicht, dass Sie "zurück" gehen wollten, und wechselt den Zustand ohne Parameter in den neuen Zustand.
Zusammenfassung
Durch Klicken auf die Schaltfläche "Zurück" wird ein Zustandswechsel in einen new - Zustand gemäß der URL ausgelöst, anstatt zum vorherigen Zustand zurückzukehren.
Daher lösen Sie das Problem, wenn Sie der URL die Parameter hinzufügen. Da die URL diskriminierend ist, landen Sie endlich in dem von Ihnen gewünschten Staat.
Hoffe es hat geholfen.
Für mich klingt dies als X Y Problem . Es gibt Möglichkeiten, Statusparameter dauerhaft zu machen, während das Problem außerhalb dieser Oberfläche liegt.
Per Definition der Frage gibt es Daten, die von Staaten unabhängig bleiben sollten. Es ist also eine Art globales Verhältnis zu Staaten. Daher sollte es einen Dienst geben, der es hält, und die Controller beider Staaten behalten es bei Bedarf bei. Übergeben Sie einfach keine Daten, die außerhalb der Zustände eines Staates in Zustandsparametern liegen.
Sticky-Zustände würden leicht zu diesem Ansatz passen, da DOM und $scope
beibehalten werden können, während ein anderer Status aktiv ist. Es hat jedoch nichts mit Zustandsparametern zu tun, wenn der Staat reaktiviert wird.