保存AngularJS中的视图状态

时间:2014-03-28 13:35:47

标签: angularjs angularjs-scope

我开发了一个HTML 5应用程序,并且有一个加载用户注释的视图。它是递归的:任何注释都可以有可点击的子注释,它们在同一视图中加载并使用相同的控制器。

一切都好。但是,当我想回去时,评论再次加载,我丢失了我的位置和我加载的子评论。

我回去后可以保存视图的状态吗?我想我可以使用某种技巧,例如:每次点击子评论并隐藏上一个视图时附加一个新视图。但我不知道该怎么做。

2 个答案:

答案 0 :(得分:23)

是的,您应该将状态保留在服务中,而不是在控制器中加载和保持UI的状态。这意味着,如果你这样做:

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精细保持状态持久化状态,但它目前是实验性的(并将以角度1.3发货)

答案 1 :(得分:1)

使用调解员

如果您使用 Mediator ,您将 Out-Degree 扇出)减少2倍。< / p>

<强>优点:

  • 您没有将模块直接连接到服务器( $ http )。
  • 您没有将模块耦合到其他服务()。
  • 状态持久性所需的一切都在你的控制器中( $ scope / $ scope。$ on $ emit $广播)。
  • 您的Mediator了解更多信息,可以更有效地指导应用程序。

<强>下行(?):

  • 您的模块需要触发有趣的事件( $ scope。$ emit('list:// added / Item',$ scope.list.id,item)

<强> mediator.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'])

<强> 项-controller.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);
};