Сохранение состояния представлений в AngularJS



Я разрабатываю приложение HTML 5 и имею представление, в котором загружаются комментарии пользователей. Это рекурсивно: любой комментарий может иметь кликабельные субкомментарии, которые загружаются в том же представлении и используют тот же контроллер.



Все в порядке. Но, когда я хочу вернуться, комментарии загружаются снова, и я теряю свою позицию и вложенные комментарии, которые я загрузил.



Можно ли сохранить состояние представления, когда я вернусь? Я подумал, что могу использовать какой-нибудь трюк, например: добавлять новый вид каждый раз, когда я нажимаю на кнопку вложите комментарий и скройте предыдущее представление. Но я не знаю, как это сделать.

528   2  

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

    Ничего не найдено.