funciones example eventos entre ejemplos controladores comunicacion javascript angularjs

javascript - example - funciones en angularjs



Mantener el modelo de alcance cuando se cambia entre vistas en AngularJS (7)

$ rootScope es una gran variable global, que está bien para cosas únicas o pequeñas aplicaciones. Use un servicio si desea encapsular su modelo y / o comportamiento (y posiblemente reutilizarlo en otro lugar). Además de la publicación del grupo de Google que mencionó el OP, consulte también https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion .

Estoy aprendiendo AngularJS. Digamos que tengo / veo1 usando My1Ctrl , y / view2 usando My2Ctrl ; que se puede navegar para usar pestañas donde cada vista tiene su propia forma simple, pero diferente.

¿Cómo me aseguraré de que los valores ingresados ​​en forma de vista1 no se restablezcan cuando un usuario se retira y luego vuelve a view1 ?

Lo que quiero decir es, ¿cómo puede la segunda visita a view1 mantener el mismo estado exacto del modelo como lo dejé?


Angular realmente no brinda lo que está buscando de manera inmediata. Lo que haría para lograr lo que está buscando es usar los siguientes complementos

UI Router & UI Router Extras

Estos dos le proporcionarán enrutamiento basado en estado y estados adhesivos, puede tabular entre estados y toda la información se guardará cuando el alcance "permanezca activo", por así decirlo.

Compruebe la documentación en ambos, ya que es bastante sencillo, ui router extra también tiene una buena demonstration de cómo funcionan los estados pegajosos.


Me tomé un poco de tiempo para pensar 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 rootscope .

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 mediante inyección de dependencia. Como los servicios son singleton, sus datos no se destruyen como los datos en el controlador.

En el servicio, tengo un modelo. el modelo SÓLO tiene datos - sin funciones -. De esta forma, se puede convertir de JSON para seguir persistiendo. Utilicé el html5 localstorage para la 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 avisarles que restauren su estado (utilizado para cuando el usuario abandona la página y presiona el botón Atrás para regresar al página respectivamente).

Servicio de ejemplo 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 luego usa un enlace como este

<h1>{{user.model.name}}</h1>

Y en el módulo de 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é, tomó un tiempo llegar a este punto. Es una manera muy limpia de hacerlo, pero es un poco de ingeniería para hacer algo que sospecho que es un problema muy común cuando se desarrolla en Angular.

Me gustaría ver las formas más sencillas pero limpias de administrar el estado de los controladores, incluso cuando el usuario se va y vuelve a la página.


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:

var app = angular.module(''otisApp'', [''chieffancypants.loadingBar'', ''ngRoute'']); app.config([''$routeProvider'', function($routeProvider){ $routeProvider.when(''/:page'', { templateUrl: function(page){return page.page + ''.html'';}, controller:''otisCtrl'' }) .otherwise({redirectTo:''/otis''}); }]);

Tengo un solo 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 las personas sugieren anteriormente y creé un servicio para ese propósito, luego lo pasé al controlador de la siguiente manera:

app.factory(''otisService'', function($http){ var service = { answers:[], ... } return service; }); app.controller(''otisCtrl'', [''$scope'', ''$window'', ''otisService'', ''$routeParams'', function($scope, $window, otisService, $routeParams){ $scope.message = "Hello from page: " + $routeParams.page; $scope.update = function(answer){ otisService.answers.push(answers); }; ... }]);

Ahora puedo llamar a la función de actualización desde cualquiera de mis vistas, pasar valores y actualizar mi modelo, no tengo necesidad de utilizar aptas html5 para datos de persistencia (esto es en mi caso, tal vez en otros casos sería necesario usar html5 apis como locallstorage y otras cosas).


Un poco tarde para una respuesta, pero solo se actualiza con algunas mejores prácticas

jsfiddle

var myApp = angular.module(''myApp'',[]); myApp.factory(''UserService'', function() { var userService = {}; userService.name = "HI Atul"; userService.ChangeName = function (value) { userService.name = value; }; return userService; }); function MyCtrl($scope, UserService) { $scope.name = UserService.name; $scope.updatedname=""; $scope.changeName=function(data){ $scope.updateServiceName(data); } $scope.updateServiceName = function(name){ UserService.ChangeName(name); $scope.name = UserService.name; } }


Una alternativa a los servicios es usar el almacén de valores.

En la base de mi aplicación agregué esto

var agentApp = angular.module(''rbAgent'', [''ui.router'', ''rbApp.tryGoal'', ''rbApp.tryGoal.service'', ''ui.bootstrap'']); agentApp.value(''agentMemory'', { contextId: '''', sessionId: '''' } ); ...

Y luego en mi controlador solo hago referencia al almacén de valores. No creo que tenga sentido si el usuario cierra el navegador.

angular.module(''rbAgent'') .controller(''AgentGoalListController'', [''agentMemory'', ''$scope'', ''$rootScope'', ''config'', ''$state'', function(agentMemory, $scope, $rootScope, config, $state){ $scope.config = config; $scope.contextId = agentMemory.contextId; ...


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 ampliable y funcionará en múltiples ámbitos y permite la selección de múltiples variables de ámbito en el mismo ámbito. Utiliza la ruta de la ruta para indexar cada ámbito, y luego los nombres de la variable de ámbito para indexar un nivel más profundo.

Crear servicio con este código:

angular.module(''restoreScope'', []).factory(''restoreScope'', [''$rootScope'', ''$route'', function ($rootScope, $route) { var getOrRegisterScopeVariable = function (scope, name, defaultValue, storedScope) { if (storedScope[name] == null) { storedScope[name] = defaultValue; } scope[name] = storedScope[name]; } var service = { GetOrRegisterScopeVariables: function (names, defaultValues) { var scope = $route.current.locals.$scope; var storedBaseScope = angular.fromJson(sessionStorage.restoreScope); if (storedBaseScope == null) { storedBaseScope = {}; } // stored scope is indexed by route name var storedScope = storedBaseScope[$route.current.$$route.originalPath]; if (storedScope == null) { storedScope = {}; } if (typeof names === "string") { getOrRegisterScopeVariable(scope, names, defaultValues, storedScope); } else if (Array.isArray(names)) { angular.forEach(names, function (name, i) { getOrRegisterScopeVariable(scope, name, defaultValues[i], storedScope); }); } else { console.error("First argument to GetOrRegisterScopeVariables is not a string or array"); } // save stored scope back off storedBaseScope[$route.current.$$route.originalPath] = storedScope; sessionStorage.restoreScope = angular.toJson(storedBaseScope); }, SaveState: function () { // get current scope var scope = $route.current.locals.$scope; var storedBaseScope = angular.fromJson(sessionStorage.restoreScope); // save off scope based on registered indexes angular.forEach(storedBaseScope[$route.current.$$route.originalPath], function (item, i) { storedBaseScope[$route.current.$$route.originalPath][i] = scope[i]; }); sessionStorage.restoreScope = angular.toJson(storedBaseScope); } } $rootScope.$on("savestate", service.SaveState); return service; }]);

Agregue este código a su función de ejecución en su módulo de aplicación:

$rootScope.$on(''$locationChangeStart'', function (event, next, current) { $rootScope.$broadcast(''savestate''); }); window.onbeforeunload = function (event) { $rootScope.$broadcast(''savestate''); };

Inyecte el servicio de restoreScope en su controlador (ejemplo a continuación):

function My1Ctrl($scope, restoreScope) { restoreScope.GetOrRegisterScopeVariables([ // scope variable name(s) ''user'', ''anotherUser'' ],[ // default value(s) { name: ''user name'', email: ''[email protected]'' }, { name: ''another user name'', email: ''[email protected]'' } ]); }

El ejemplo anterior inicializará $ scope.user en el valor almacenado; de lo contrario, se establecerá de manera predeterminada en el valor provisto y se guardará. Si la página se cierra, se actualiza o la ruta cambia, los valores actuales de todas las variables de ámbito registradas se guardarán y se restaurarán la próxima vez que se visite la ruta / página.