问题描述
我的角应用程序有2个控制器。 我的问题是,当用户离开页面时,控制器不会保留数据。
如何将控制器上的选定数据存储到数据存储中,以便在其他控制器之间使用?
1楼
Jossef Harush
27
已采纳
2015-07-25 12:27:07
选项1 - 定制service
您可以利用专用的角度服务在控制器之间存储和共享数据( 是单实例对象)
服务定义
app.service('commonService', function ($http) {
var info;
return {
getInfo: getInfo,
setInfo: setInfo
};
// .................
function getInfo() {
return info;
}
function setInfo(value) {
info = value;
}
});
用于多个控制器
app.controller("HomeController", function ($scope, commonService) {
$scope.setInfo = function(value){
commonService.setInfo(value);
};
});
app.controller("MyController", function ($scope, commonService) {
$scope.info = commonService.getInfo();
});
选项2 - html5 localStorage
您可以使用内置浏览器本地存储并从任何地方存储数据
写作
$window.localStorage['my-data'] = 'hello world';
读
var data = $window.localStorage['my-data']
// ...
- 看看这个很棒的项目: :
选项3 - 通过Web服务器API
如果需要在不同用户之间保存数据,则应将其保存在服务器端的某个位置(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);
}
2楼
scraymer
5
2015-07-25 12:31:15
编辑请参阅回答,他写了深入的回复,其中包括其他方法,包括这一方法。
我建议使用localStorage或sessionStorage - 。
HTML本地存储提供了两个用于在客户端上存储数据的对象:
- window.localStorage - 存储没有过期日期的数据
- window.sessionStorage - 存储一个会话的数据(浏览器选项卡关闭时数据丢失)
这假设您不希望将数据POST / PUT到您的Web服务(在您的问题中提到Windows服务)。
如果您的数据是数组或某种类型,您可以将其转换为JSON以存储为字符串,然后在需要时您可以按如下方式解析 - :
var names = [];
names[0] = prompt("New member name?");
localStorage["names"] = JSON.stringify(names);
//...
var storedNames = JSON.parse(localStorage["names"]);
3楼
DanteTheSmith
3
2017-11-03 12:55:56
在其他答案(AFAIK)中没有提到选项。
活动
您可以使用事件在控制器之间进行通信。
这是一种简单的通信,不需要中介(如服务),也不能被用户擦除(如HTML存储)。
所有代码都写在您尝试与之通信的控制器中,因此非常透明。
下面将介绍如何利用事件在控制器之间进行通信的一个很好的示例。
出版商是想要发布的范围(换句话说,让别人知道发生了什么)。 大多数人并不关心发生了什么,也不是这个故事的一部分。
订阅者是关心某个事件已经发布的用户(换句话说,当它被通知时,嘿,这发生了,它会做出反应)。
我们将使用$ rootScope作为发布者和订阅者之间的中介 。 这总是有效的,因为无论范围发出什么事件,$ rootScope都是该范围的父级或父级父级的父级。当$ rootScope广播(告诉所有继承的人)关于某个事件时,每个人都会听到(因为$ rootScope只是那个,范围继承树的根)所以app中的每个其他范围都是它的孩子或孩子的孩子的孩子。
// 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;
});
}]);
上面我们看到两个控制器使用事件向对方传达消息。 该事件具有名称,它必须是唯一的,否则,订户不区分事件。 事件参数保存自动生成但有时有用的数据,消息是有效负载。 在这个例子中,它是一个字符串,但它可以是任何对象。 因此,只需将您希望在对象内部传递的所有数据放入对象中,然后通过事件发送即可。
注意:
为了这个目的, 您可以避免使用根作用域 (并限制获得事件通知的控制器的数量) ,以防两个作用域在彼此的直接继承行中。 进一步说明如下:
$ rootScope。$ emit只允许其他$ rootScope侦听器捕获它。 当你不希望每个$ scope获得它时,这很好。 主要是高级别的沟通。 可以把它想象成成年人在一个房间里互相交谈,这样孩子们就听不到了。
$ rootScope。$ broadcast是一种几乎可以听到它的方法。 这相当于父母大喊大叫,晚餐准备就绪,所以房子里的每个人都听到了。
$ scope。$ emit是你希望$ scope及其所有父项和$ rootScope听到事件的时间。 这是一个在家里向父母抱怨的孩子(但不是在其他孩子可以听到的杂货店)。 当您想要从作为订阅者的子或第n个孩子的发布者进行通信时,这是一种快捷方式。
$ scope。$ broadcast用于$ scope本身及其子节点。 这是一个孩子对它的毛绒动物窃窃私语,所以他们的父母听不到。
编辑:我认为有一个更详细的例子的plunker就足够了所以我决定在这里保持简单。 这个精心解释应该更好。
4楼
mofojed
1
2015-07-25 12:28:58
要在同一页面上的两个控制器之间共享数据,您可以使用工厂/服务。 例如,查看 。
但是,如果这是跨页面重新加载/刷新,则需要将数据存储在本地存储中,然后在重新加载时读取它。 这方面的一个例子是:
5楼
Rannie Aguilar Peralta
0
2019-06-11 05:10:10
查看此库
这可以帮助您更轻松地管理应用程序状态,因为它会迫使您在应用程序上拥有单向数据流。