Me tomé un poco de tiempo para averiguar cuál es la mejor manera de hacerlo. También quería mantener el estado, cuando el usuario abandona la página y luego presiona el botón Atrás, para volver a la página anterior; y no solo poner todos mis datos en el rootcope .
El resultado final es tener un servicio para cada controlador . En el controlador, solo tiene funciones y variables que no le importan, si se borran.
El servicio para el controlador se inyecta por inyección de dependencia. Como los servicios son singletons, sus datos no se destruyen como los datos en el controlador.
En el servicio, tengo un modelo. el modelo SOLO tiene datos, sin funciones. De esa manera, se puede convertir de JSON de un lado a otro para mantenerlo. Usé el almacenamiento local html5 para persistencia.
Por último, utilicé window.onbeforeunload
y $rootScope.$broadcast('saveState');
para que todos los servicios sepan que deben guardar su estado, y $rootScope.$broadcast('restoreState')
para que sepan cómo restaurar su estado (utilizado cuando el usuario abandona la página y presiona el botón Atrás para volver a la página respectivamente).
Ejemplo de servicio llamado userService para mi 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;
}]);
ejemplo de userController
function userCtrl($scope, userService) {
$scope.user = userService;
}
La vista usa un enlace como este
<h1>{{user.model.name}}</h1>
Y en el módulo de la aplicación , dentro de la función de ejecución, manejo la transmisión de saveState y 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');
};
Como mencioné, esto tomó un tiempo para llegar a este punto. Es una forma muy limpia de hacerlo, pero es un poco de ingeniería hacer algo que sospecho que es un problema muy común cuando se desarrolla en Angular.
Me encantaría ver más fácilmente, pero como formas limpias de manejar el mantenimiento del estado en todos los controladores, incluso cuando el usuario se va y vuelve a la página.
sessionStorage.restoreState
está configurado"true"
. Para obtener una solución correcta para conservar los datos cuando se actualiza la página, mira aquí . Para datos persistentes cuando la ruta cambia, mire la respuesta de carloscarcamo. Todo lo que necesita es poner los datos en un servicio.$scope.user = userService;
usted tiene algo como esto:$scope.name = userService.model.name; $scope.email = userService.model.email;
. ¿Funcionará o cambiar las variables a la vista no lo cambiaría en el Servicio?Un poco tarde para una respuesta, pero acaba de actualizar el violín con algunas mejores prácticas
jsfiddle
fuente
updateService
debería llamarse cuando se destruye el controlador$scope.$on('$destroy', function() { console.log('Ctrl destroyed'); $scope.updateServiceName($scope.name); });
$ rootScope es una gran variable global, que está bien para cosas únicas o aplicaciones pequeñas. Use un servicio si desea encapsular su modelo y / o comportamiento (y posiblemente reutilizarlo en otro lugar). Además del grupo de Google, publique el OP mencionado, consulte también https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion .
fuente
Angular realmente no proporciona lo que está buscando fuera de la caja. Lo que haría para lograr lo que busca es usar los siguientes complementos
UI Router y UI Router Extras
Estos dos le proporcionarán enrutamiento basado en estado y estados fijos, puede tabular entre estados y toda la información se guardará a medida que el alcance "se mantenga vivo", por así decirlo.
Verifique la documentación en ambos, ya que es bastante sencillo, los extras del enrutador ui también tienen una buena demostración de cómo funcionan los estados fijos.
fuente
Tuve el mismo problema, esto es lo que hice: tengo un SPA con múltiples vistas en la misma página (sin ajax), así que este es el código del módulo:
Solo tengo un controlador para todas las vistas, pero el problema es el mismo que el de la pregunta, el controlador siempre actualiza los datos, para evitar este comportamiento hice lo que la gente sugiere anteriormente y creé un servicio para ese propósito, luego lo pasé al controlador de la siguiente manera:
Ahora puedo llamar a la función de actualización desde cualquiera de mis vistas, pasar valores y actualizar mi modelo, no he necesitado usar html5 apis para datos de persistencia (esto es en mi caso, tal vez en otros casos sería necesario usar html5 apis como localstorage y otras cosas).
fuente
Una alternativa a los servicios es usar el almacén de valores.
En la base de mi aplicación agregué esto
Y luego, en mi controlador, solo hago referencia al almacén de valores. No creo que tenga sentido si el usuario cierra el navegador.
fuente
Solución que funcionará para múltiples ámbitos y múltiples variables dentro de esos ámbitos
Este servicio se basó en la respuesta de Anton, pero es más extensible y funcionará en varios ámbitos y permite la selección de múltiples variables de alcance en el mismo alcance. Utiliza la ruta de ruta para indexar cada ámbito, y luego los nombres de las variables de ámbito para indexar un nivel más profundo.
Crear servicio con este código:
Agregue este código a su función de ejecución en el módulo de su aplicación:
Inyecte el servicio restoreScope en su controlador (ejemplo a continuación):
El ejemplo anterior inicializará $ scope.user en el valor almacenado; de lo contrario, el valor predeterminado se guardará de manera predeterminada. Si la página se cierra, se actualiza o se cambia la ruta, los valores actuales de todas las variables de alcance registradas se guardarán y se restaurarán la próxima vez que se visite la ruta / página.
fuente
Puede usar el
$locationChangeStart
evento para almacenar el valor anterior en$rootScope
o en un servicio. Cuando regrese, simplemente inicialice todos los valores almacenados previamente. Aquí hay una demostración rápida usando$rootScope
.fuente