Javascript Angularjs 数据存储最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31626360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angularjs Best Practice for Data Store
提问by Bryan Krossley
My angular app have 2 controllers. My problem is that the controllers does not keep the data when the user navigates away from the page.
我的 angular 应用程序有 2 个控制器。我的问题是,当用户离开页面时,控制器不会保留数据。
How can I store the selected data on of my controllers into a data store so it can be used between other controllers?
如何将选定的控制器上的数据存储到数据存储中,以便在其他控制器之间使用?
回答by Jossef Harush
Option 1 - custom service
选项 1 - 自定义 service
You can utilize a dedicated angular service to store and share data between controllers (servicesare single instance objects)
您可以利用专用的角度服务在控制器之间存储和共享数据(服务是单实例对象)
service definition
服务定义
app.service('commonService', function ($http) {
var info;
return {
getInfo: getInfo,
setInfo: setInfo
};
// .................
function getInfo() {
return info;
}
function setInfo(value) {
info = value;
}
});
usage in multiple controllers
在多个控制器中的使用
app.controller("HomeController", function ($scope, commonService) {
$scope.setInfo = function(value){
commonService.setInfo(value);
};
});
app.controller("MyController", function ($scope, commonService) {
$scope.info = commonService.getInfo();
});
Option 2 - html5 localStorage
选项 2 - html5 localStorage
You can use the built-in browser local storage and store your data from anywhere
您可以使用内置的浏览器本地存储并从任何地方存储您的数据
writing
写作
$window.localStorage['my-data'] = 'hello world';
reading
读
var data = $window.localStorage['my-data']
// ...
- check out this awesome project: https://github.com/grevory/angular-local-storage
- 看看这个很棒的项目:https: //github.com/grevory/angular-local-storage
Option 3 - via web server api
选项 3 - 通过 Web 服务器 API
If you need to persist data among different users, you should save it somewhere in the server side (db / cache)
如果你需要在不同用户之间持久化数据,你应该把它保存在服务器端的某个地方(db / cache)
function getProfile() {
return $http.get(commonService.baseApi + '/api/profile/');
}
function updateProfile(data) {
var json = angular.toJson(data);
return $http.post(commonService.baseApi + '/api/profile/', json);
}
回答by scraymer
EDITSee Jossef Harush'sanswer where he has written an in-depth response that covers other methods including this one.
编辑参见Jossef Harush 的回答,他写了一篇深入的回答,涵盖了包括这个在内的其他方法。
I'd recommend using either localStorage or sessionStorage - http://www.w3schools.com/html/html5_webstorage.asp.
我建议使用 localStorage 或 sessionStorage - http://www.w3schools.com/html/html5_webstorage.asp。
HTML local storage provides two objects for storing data on the client:
- window.localStorage - stores data with no expiration date
- window.sessionStorage - stores data for one session (data is lost when the browser tab is closed)
HTML 本地存储提供了两个对象用于在客户端存储数据:
- window.localStorage - 存储没有到期日期的数据
- window.sessionStorage - 存储一个会话的数据(关闭浏览器选项卡时数据丢失)
This assumes that you don't want to POST/PUT the data to your web service (windows service mention in your question).
这假设您不想将数据 POST/PUT 到您的 Web 服务(您的问题中提到了 Windows 服务)。
If you data is an array or some sort, you can convert it to JSON to store as a string and then when you need it you can parse it back as follows - How do I store an array in localStorage?:
如果您的数据是数组或某种类型,则可以将其转换为 JSON 以存储为字符串,然后在需要时可以按如下方式解析它 -如何在 localStorage 中存储数组?:
var names = [];
names[0] = prompt("New member name?");
localStorage["names"] = JSON.stringify(names);
//...
var storedNames = JSON.parse(localStorage["names"]);
回答by DanteTheSmith
There is an option not mentioned in other answers (AFAIK).
其他答案(AFAIK)中没有提到一个选项。
EVENTS
活动
You can use events for communication between controllers.
It's a straightforward communication that doesn't need a mediator (like service) and can't be wiped by the user (like HTML storage).
All the code is written in controllers that you are trying to communicate with and thus very transparent.
您可以使用事件在控制器之间进行通信。
这是一种直接的通信,不需要中介(如服务)并且不能被用户擦除(如 HTML 存储)。
所有代码都写在您试图与之通信的控制器中,因此非常透明。
A good example how to leverage events to communicate between controllers can be seen below.
下面是如何利用事件在控制器之间进行通信的一个很好的例子。
The publisheris the scope that wanna publish (in other words let others know something happened). Most don't care about what has happened and are not part of this story.
发布者是想要发布的范围(换句话说,让其他人知道发生了一些事情)。大多数人并不关心发生了什么,也不在这个故事中。
The subscriberis the one that cares that certain event has been published (in other words when it gets notified hey, this happened, it reacts).
订阅者是关心某个事件是否已经发布的人(换句话说,当它收到通知时,嘿,这发生了,它会做出反应)。
We will use $rootScope as a mediatorbetween publisher and a subscriber.This always works because whatever scope emits an event, $rootScope is a parent of that scope or parent of a parent of a parent.. When $rootScope broadcasts (tells everyone who inherits) about an event, everyone hears (since $rootScope is just that, the root of the scope inheritance tree) so every other scope in app is a child of it or child of a child of a child..
我们将使用 $rootScope 作为发布者和订阅者之间的中介。这总是有效的,因为无论作用域发出事件,$rootScope 是该作用域的父级或父级的父级的父级。那,范围继承树的根)所以应用程序中的每个其他范围都是它的孩子或孩子的孩子的孩子..
// publisher
angular.module('test', []).controller('CtrlPublish', ['$rootScope','$scope',
function ($rootScope, $scope) {
$scope.send = function() {
$rootScope.$broadcast('eventName', 'message');
};
}]);
// subscriber
angular.module('test').controller('ctrlSubscribe', ['$scope',
function ($scope) {
$scope.$on('eventName', function (event, arg) {
$scope.receiver = 'got your ' + arg;
});
}]);
Above we see two controllers communicating a message to each other using an event. The event has a name, it has to be unique, otherwise, a subscriber doesn't differentiate between events. The event parameter holds autogenerated but sometimes useful data, the message is the payload. In this example, it's a string but it can be any object. So simply put all the data you wish to communicate inside an object and send it via event.
上面我们看到两个控制器使用一个事件相互传递消息。事件有一个名称,它必须是唯一的,否则订阅者无法区分事件。event 参数包含自动生成但有时有用的数据,消息是有效负载。在这个例子中,它是一个字符串,但它可以是任何对象。因此,只需将您希望通信的所有数据放在一个对象中并通过事件发送即可。
NOTE:
笔记:
You can avoid using root scopefor this purpose (and limit the number of controllers that get notified of an event) in case two scopes are in direct inheritance lineof each other. Further explanation below:
您可以避免为此目的使用根范围(并限制收到事件通知的控制器数量),以防两个范围彼此直接继承。进一步解释如下:
$rootScope.$emitonly lets other $rootScope listeners catch it. This is good when you don't want every $scope to get it. Mostly a high level communication. Think of it as adults talking to each other in a room so the kids can't hear them.
$rootScope.$emit只允许其他 $rootScope 侦听器捕获它。当您不希望每个 $scope 都得到它时,这很好。主要是高层沟通。把它想象成成年人在一个房间里互相交谈,所以孩子们听不到他们的声音。
$rootScope.$broadcastis a method that lets pretty much everything hear it. This would be the equivalent of parents yelling that dinner is ready so everyone in the house hears it.
$rootScope.$broadcast是一种让几乎所有东西都能听到的方法。这相当于父母大喊晚餐准备好了,所以房子里的每个人都能听到。
$scope.$emitis when you want that $scope and all its parents and $rootScope to hear the event. This is a child whining to their parents at home (but not at a grocery store where other kids can hear). This is a shortcut to use when you wanna communicate from the publisher that is a child or n-th child of the subscriber.
$scope.$emit是当您希望 $scope 及其所有父级和 $rootScope 听到事件时。这是一个孩子在家里向父母抱怨(但不是在其他孩子可以听到的杂货店)。当您想与作为订阅者的孩子或第 n 个孩子的发布者进行通信时,这是一种快捷方式。
$scope.$broadcastis for the $scope itself and its children. This is a child whispering to its stuffed animals so their parents can't hear.
$scope.$broadcast用于 $scope 本身及其子项。这是一个孩子对它的毛绒动物耳语,所以他们的父母听不到。
EDIT: I thought plunker with a more elaborate example would be enough so I decided to keep is simple here. This elaborate explanation should be better.
编辑:我认为 plunker 有一个更详细的例子就足够了,所以我决定在这里保持简单。这个详细的解释应该更好。
回答by mofojed
To share data between two controllers on the same page, you can use factories/services. Take a look at Share data between AngularJS controllersfor example.
要在同一页面上的两个控制器之间共享数据,您可以使用工厂/服务。例如,看看在AngularJS 控制器之间共享数据。
However, if this is across page reloads/refreshes, you will need to store the data in local storage and then read it upon reloading. An example of that is here: How do I store data in local storage using Angularjs?
但是,如果这是跨页面重新加载/刷新,您将需要将数据存储在本地存储中,然后在重新加载时读取它。一个例子在这里:如何使用 Angularjs 在本地存储中存储数据?
回答by Rannie Aguilar Peralta
Checkout this library https://www.npmjs.com/package/angularjs-store
签出这个库https://www.npmjs.com/package/angularjs-store
This can help you manage your application state much simpler as it will force you to have a one way data flow on your application.
这可以帮助您更轻松地管理应用程序状态,因为它将迫使您在应用程序上使用单向数据流。