Сохранение состояния представлений в AngularJS
Я разрабатываю приложение HTML 5 и имею представление, в котором загружаются комментарии пользователей. Это рекурсивно: любой комментарий может иметь кликабельные субкомментарии, которые загружаются в том же представлении и используют тот же контроллер.
Все в порядке. Но, когда я хочу вернуться, комментарии загружаются снова, и я теряю свою позицию и вложенные комментарии, которые я загрузил.
Можно ли сохранить состояние представления, когда я вернусь? Я подумал, что могу использовать какой-нибудь трюк, например: добавлять новый вид каждый раз, когда я нажимаю на кнопку вложите комментарий и скройте предыдущее представление. Но я не знаю, как это сделать.
2 ответов:
Да, вместо загрузки и сохранения состояния пользовательского интерфейса внутри контроллеров, вы должны сохранить состояние в службе. Это означает, если вы делаете это:
app.config(function($routeProvider){ $routeProvider.when('/', { controller: 'MainCtrl' }).when('/another', { controller: 'SideCtrl' }); }); app.controller('MainCtrl', function($scope){ $scope.formData = {}; $scope./* other scope stuff that deal with with your current page*/ $http.get(/* init some data */); });Вы должны изменить код инициализации на свой сервис, а также состояние там, таким образом, вы можете сохранить состояние между несколькими представлениями:
app.factory('State', function(){ $http.get(/* init once per app */); return { formData:{}, }; }); app.config(function($routeProvider){ $routeProvider.when('/', { controller: 'MainCtrl' }).when('/another', { controller: 'SideCtrl' }); }); app.controller('MainCtrl', function($scope, State){ $scope.formData = State.formData; $scope./* other scope stuff that deal with with your current page*/ }); app.controller('SideCtrl', function($scope, State){ $scope.formData = State.formData; // same state from MainCtrl }); app.directive('myDirective', function(State){ return { controller: function(){ State.formData; // same state! } }; });Когда вы возвращаетесь к своим представлениям, их состояние будет сохранено, потому что ваша служба-это синглет, который был инициализирован, когда вы впервые ввели его в систему. ваш контроллер.
Есть также Новый
ui.router, который имеет машину состояний, это низкоуровневая версия$routeProvider, и вы можете сохранить состояние мелкозернистого зерна с помощью$stateProvider, но в настоящее время он экспериментальный (и будет поставляться на angular 1.3)
Используйте посредника
Если вы используете медиатор , Вы будете уменьшать свою степень выхода (Fan-Out ) с коэффициентом 2.
Преимущества:
- вы не подключаете модуль непосредственно к серверу ($http).
- вы не подключаете модуль к дополнительной службе ( Состояние).
- Все, что вам нужно для сохранения состояния, находится прямо в вашем контроллере ($scope / $сфера применения.$on , $испускают, $трансляция ).
Ваш посредник знает больше и может направлять приложение более эффективно.Обратная сторона(?):
- ваши модули должны запускать интересные события ($scope.$испустить('список://добавил/пункт', $объем.список.идентификатор, элемент))
посредник.js
angular.module('lists.mediator', ['lists', 'list', 'item']).run(function mediate($rootScope){ var lists = []; $rootScope.lists = lists; $rootScope.$watch('lists', yourWatcher, true); function itemModuleOrControllerStartedHandler(e, itemId, disclose){ if(!lists.length){ $http.get(...).success(function(data){ lists.push.apply(lists, data); var item = getItem(lists, itemId); disclose(item); // do not copy object otherwise you'll have to manage changes to stay synchronized }); } else { var item = getItem(lists, itemId); disclose(item); } } $rootScope.$on('item://started', itemModuleOrControllerStartedHandler); }); // angular.bootstrap(el, ['lists.mediator'])элемент-контроллер.js
var ItemController = function ItemController($scope, $routeParams){ var disclosure = $scope.$emit.bind($scope, 'item://received/data', (+new Date())); $scope.itemId = $routeParams.id; $scope.item = { id: -1, name: 'Nameless :(', quantity: 0 }; function itemDataHandler(e, timestamp, item){ $scope.item = item; } $scope.$on('item://received/data', itemDataHandler); $scope.$emit('item://started', $scope.id, disclosure); };
Comments