如何使用angular.js维护SPA中的页面状态

时间:2022-07-04 21:17:36

Using a Single Page Architecture, every time the uses goes to a particular page, the controller for that page is run. I need to maintain alot of state across the various SPA pages.

使用单页面体系结构,每次使用到特定页面时,都会运行该页面的控制器。我需要在各个SPA页面上保持很多状态。

Question: what is the proper way to maintain state across controllers (SPA pages) without polluting the $rootScope?

问题:在不污染$ rootScope的情况下,跨控制器(SPA页面)维护状态的正确方法是什么?

For some reason, it does not seem "proper" to use a service for managing state.

出于某种原因,使用服务来管理状态似乎并不“合适”。

Thanks, -Andres

谢谢,-Andres

2 个解决方案

#1


1  

The answer is to use Services. Services are singleton objects that can be injected into multiple controllers, that can be used to store state.

答案是使用服务。服务是单个对象,可以注入多个控制器,可用于存储状态。

Within your state, you can use some kind of caching mechanism like localStorage, or sessionStorage to maintain persistent storage

在您的州内,您可以使用某种缓存机制(如localStorage或sessionStorage)来维护持久存储

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!
    }
  };
});

Code courtesy

代码礼貌

#2


3  

It's not a good practice to store your state directly inside of $rootScope.

将状态直接存储在$ rootScope中并不是一个好习惯。

Why ?

为什么?

Because during the digest cycle of angular (dirty checking), rootScope will check that every scope watchers of the application are "stable", this means many, many, many loop inside the DOM to check for modifications and this is really heavy...

因为在角度(脏检查)的摘要循环期间,rootScope将检查应用程序的每个范围观察者是否“稳定”,这意味着在DOM内部有很多很多循环来检查修改,这真的很重...

However, you can make something better, and you have multiple solutions :

但是,您可以做出更好的事情,并且您有多种解决方案:

Solution 1 - Your component/directive tree fits your state tree

解决方案1 ​​ - 您的组件/指令树适合您的状态树

Use higher order directives / components that hold the state and pass the data through child components/directives. This way everything is managed in the parent and you don't have to store anything anywhere else, giving you with stateless components. Pretty simple solution when your component tree match your state tree.

使用保存状态的高阶指令/组件,并通过子组件/指令传递数据。这样,所有内容都在父级中进行管理,您无需在其他任何位置存储任何内容,从而为您提供无状态组件。组件树与状态树匹配时非常简单的解决方案。

Solution 2 - Your component/directive tree doesnt fit your state tree

解决方案2 - 您的组件/指令树不适合您的状态树

You can use angular services to store some kind of information directly inside of them and reuse the state everywhere you need. I don't really like this solution since every services (factory / providers / services) in angularjs are singleton, and it's an anti pattern...

您可以使用角度服务直接在其中存储某种信息,并在您需要的任何地方重用该状态。我不太喜欢这个解决方案,因为angularjs中的每个服务(工厂/提供商/服务)都是单身,而且它是反模式......

Solution 3 - Redux

解决方案3 - Redux

Redux has been presented (and almost used) by the Reactjs community, but it's not only for React.

Redux已经被Reactjs社区呈现(并且几乎被使用),但它不仅仅适用于React。

You can use it with Angularjs, Angular 2 etc... If your component tree doesn't fit your state tree, I suggest you to take an eye on this library that works pretty well in any frontend javascript project / fw.

您可以将它与Angularjs,Angular 2等一起使用......如果您的组件树不适合您的状态树,我建议您关注这个在任何前端javascript项目/ fw中运行良好的库。

#1


1  

The answer is to use Services. Services are singleton objects that can be injected into multiple controllers, that can be used to store state.

答案是使用服务。服务是单个对象,可以注入多个控制器,可用于存储状态。

Within your state, you can use some kind of caching mechanism like localStorage, or sessionStorage to maintain persistent storage

在您的州内,您可以使用某种缓存机制(如localStorage或sessionStorage)来维护持久存储

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!
    }
  };
});

Code courtesy

代码礼貌

#2


3  

It's not a good practice to store your state directly inside of $rootScope.

将状态直接存储在$ rootScope中并不是一个好习惯。

Why ?

为什么?

Because during the digest cycle of angular (dirty checking), rootScope will check that every scope watchers of the application are "stable", this means many, many, many loop inside the DOM to check for modifications and this is really heavy...

因为在角度(脏检查)的摘要循环期间,rootScope将检查应用程序的每个范围观察者是否“稳定”,这意味着在DOM内部有很多很多循环来检查修改,这真的很重...

However, you can make something better, and you have multiple solutions :

但是,您可以做出更好的事情,并且您有多种解决方案:

Solution 1 - Your component/directive tree fits your state tree

解决方案1 ​​ - 您的组件/指令树适合您的状态树

Use higher order directives / components that hold the state and pass the data through child components/directives. This way everything is managed in the parent and you don't have to store anything anywhere else, giving you with stateless components. Pretty simple solution when your component tree match your state tree.

使用保存状态的高阶指令/组件,并通过子组件/指令传递数据。这样,所有内容都在父级中进行管理,您无需在其他任何位置存储任何内容,从而为您提供无状态组件。组件树与状态树匹配时非常简单的解决方案。

Solution 2 - Your component/directive tree doesnt fit your state tree

解决方案2 - 您的组件/指令树不适合您的状态树

You can use angular services to store some kind of information directly inside of them and reuse the state everywhere you need. I don't really like this solution since every services (factory / providers / services) in angularjs are singleton, and it's an anti pattern...

您可以使用角度服务直接在其中存储某种信息,并在您需要的任何地方重用该状态。我不太喜欢这个解决方案,因为angularjs中的每个服务(工厂/提供商/服务)都是单身,而且它是反模式......

Solution 3 - Redux

解决方案3 - Redux

Redux has been presented (and almost used) by the Reactjs community, but it's not only for React.

Redux已经被Reactjs社区呈现(并且几乎被使用),但它不仅仅适用于React。

You can use it with Angularjs, Angular 2 etc... If your component tree doesn't fit your state tree, I suggest you to take an eye on this library that works pretty well in any frontend javascript project / fw.

您可以将它与Angularjs,Angular 2等一起使用......如果您的组件树不适合您的状态树,我建议您关注这个在任何前端javascript项目/ fw中运行良好的库。