Ich habe mir ein bisschen Zeit genommen, um herauszufinden, wie das am besten geht. Ich wollte auch den Status beibehalten, wenn der Benutzer die Seite verlässt und dann die Zurück-Taste drückt, um zur alten Seite zurückzukehren. und nicht nur alle meine Daten in das Rootscope legen .
Das Endergebnis ist ein Service für jeden Controller . In der Steuerung haben Sie nur Funktionen und Variablen, die Sie nicht interessieren, wenn sie gelöscht werden.
Der Dienst für die Steuerung wird durch Abhängigkeitsinjektion injiziert. Da Dienste Singletons sind, werden ihre Daten nicht wie die Daten in der Steuerung zerstört.
Im Service habe ich ein Modell. Das Modell hat NUR Daten - keine Funktionen -. Auf diese Weise kann es von JSON hin und her konvertiert werden, um es beizubehalten. Ich habe den HTML5-Localstorage für die Persistenz verwendet.
Zuletzt habe ich verwendet window.onbeforeunload
und $rootScope.$broadcast('saveState');
alle Dienste wissen lassen, dass sie ihren Status speichern sollen, und $rootScope.$broadcast('restoreState')
um sie wissen zu lassen , dass sie ihren Status wiederherstellen sollen (wird verwendet, wenn der Benutzer die Seite verlässt und die Zurück-Taste drückt, um jeweils zur Seite zurückzukehren).
Beispieldienst namens userService für meinen userController :
app.factory('userService', ['$rootScope', function ($rootScope) {
var service = {
model: {
name: '',
email: ''
},
SaveState: function () {
sessionStorage.userService = angular.toJson(service.model);
},
RestoreState: function () {
service.model = angular.fromJson(sessionStorage.userService);
}
}
$rootScope.$on("savestate", service.SaveState);
$rootScope.$on("restorestate", service.RestoreState);
return service;
}]);
userController Beispiel
function userCtrl($scope, userService) {
$scope.user = userService;
}
Die Ansicht verwendet dann eine solche Bindung
<h1>{{user.model.name}}</h1>
Und im App-Modul kümmere ich mich innerhalb der Ausführungsfunktion um die Übertragung von saveState und restoreState
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (sessionStorage.restorestate == "true") {
$rootScope.$broadcast('restorestate'); //let everything know we need to restore state
sessionStorage.restorestate = false;
}
});
//let everthing know that we need to save state now.
window.onbeforeunload = function (event) {
$rootScope.$broadcast('savestate');
};
Wie ich bereits erwähnte, dauerte es eine Weile, bis dieser Punkt erreicht war. Es ist eine sehr saubere Art, dies zu tun, aber es ist ein gutes Stück Technik, etwas zu tun, von dem ich vermuten würde, dass es ein sehr häufiges Problem bei der Entwicklung in Angular ist.
Ich würde es gerne einfacher sehen, aber als saubere Möglichkeit, den Status zwischen den Controllern beizubehalten, auch wenn der Benutzer die Seite verlässt und zur Seite zurückkehrt.
sessionStorage.restoreState
ist"true"
. Eine korrekte Lösung zum Beibehalten von Daten beim Aktualisieren der Seite finden Sie hier . Informationen zu dauerhaften Daten, wenn sich die Route ändert, finden Sie in der Antwort von carloscarcamo. Sie müssen lediglich die Daten in einen Dienst stellen.$scope.user = userService;
Sie haben so etwas :$scope.name = userService.model.name; $scope.email = userService.model.email;
. Funktioniert es oder ändert sich das Ändern der angezeigten Variablen im Service nicht?Ein bisschen spät für eine Antwort, aber gerade aktualisiert Geige mit einigen Best Practice
jsfiddle
quelle
updateService
aufgerufen werden sollte, wenn der Controller zerstört wird -$scope.$on('$destroy', function() { console.log('Ctrl destroyed'); $scope.updateServiceName($scope.name); });
$ rootScope ist eine große globale Variable, die für einmalige Dinge oder kleine Apps geeignet ist. Verwenden Sie einen Dienst, wenn Sie Ihr Modell und / oder Verhalten kapseln möchten (und es möglicherweise an anderer Stelle wiederverwenden möchten). Neben dem erwähnten Google-Gruppenbeitrag siehe OP auch https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion .
quelle
Angular bietet nicht wirklich das, wonach Sie suchen. Was ich tun würde, um das zu erreichen, wonach Sie suchen, ist die Verwendung der folgenden Add-Ons
UI Router & UI Router Extras
Diese beiden bieten Ihnen zustandsbasiertes Routing und Sticky-Status. Sie können zwischen Status wechseln und alle Informationen werden gespeichert, wenn der Bereich sozusagen "am Leben bleibt".
Überprüfen Sie die Dokumentation zu beiden, da es ziemlich einfach ist. Die Extras des UI-Routers zeigen auch gut , wie Sticky States funktionieren.
quelle
Ich hatte das gleiche Problem. Folgendes habe ich getan: Ich habe ein SPA mit mehreren Ansichten auf derselben Seite (ohne Ajax). Dies ist also der Code des Moduls:
Ich habe nur einen Controller für alle Ansichten, aber das Problem ist das gleiche wie die Frage, der Controller aktualisiert immer Daten. Um dieses Verhalten zu vermeiden, habe ich die oben vorgeschlagenen Schritte ausgeführt und einen Dienst für diesen Zweck erstellt und dann übergeben an die Steuerung wie folgt:
Jetzt kann ich die Aktualisierungsfunktion aus jeder meiner Ansichten aufrufen, Werte übergeben und mein Modell aktualisieren. Ich muss keine HTML5-APIs für Persistenzdaten verwenden (dies ist in meinem Fall möglicherweise in anderen Fällen erforderlich, um HTML5 zu verwenden apis wie localstorage und andere Sachen).
quelle
Eine Alternative zu Diensten ist die Verwendung des Wertspeichers.
In der Basis meiner App habe ich dies hinzugefügt
Und dann verweise ich in meinem Controller nur auf den Wertspeicher. Ich denke nicht, dass es etwas bringt, wenn der Benutzer den Browser schließt.
quelle
Lösung, die für mehrere Bereiche und mehrere Variablen in diesen Bereichen funktioniert
Dieser Service basiert auf Antons Antwort, ist jedoch erweiterbarer und funktioniert über mehrere Bereiche hinweg und ermöglicht die Auswahl mehrerer Bereichsvariablen im selben Bereich. Es verwendet den Routenpfad, um jeden Bereich zu indizieren, und dann die Namen der Bereichsvariablen, um eine Ebene tiefer zu indizieren.
Erstellen Sie einen Dienst mit diesem Code:
Fügen Sie diesen Code Ihrer Ausführungsfunktion in Ihrem App-Modul hinzu:
Injizieren Sie den restoreScope-Dienst in Ihren Controller (Beispiel unten):
Im obigen Beispiel wird $ scope.user mit dem gespeicherten Wert initialisiert, andernfalls wird standardmäßig der angegebene Wert verwendet und dieser gespeichert. Wenn die Seite geschlossen, aktualisiert oder die Route geändert wird, werden die aktuellen Werte aller registrierten Bereichsvariablen gespeichert und beim nächsten Besuch der Route / Seite wiederhergestellt.
quelle
Mit
$locationChangeStart
event können Sie den vorherigen Wert in$rootScope
oder in einem Service speichern . Wenn Sie zurückkommen, initialisieren Sie einfach alle zuvor gespeicherten Werte. Hier ist eine kurze Demo mit$rootScope
.quelle