Javascript Angularjs数据存储最佳实践

Javascript Angularjs数据存储最佳实践,javascript,angularjs,Javascript,Angularjs,我的angular应用程序有两个控制器。我的问题是,当用户离开页面导航时,控制器不会保留数据 如何将控制器上的选定数据存储到数据存储中,以便在其他控制器之间使用?选项1-自定义服务 您可以利用专用的angular服务在控制器之间存储和共享数据(是单实例对象) 服务定义 app.service('commonService', function ($http) { var info; return { getInfo: getInfo,

我的angular应用程序有两个控制器。我的问题是,当用户离开页面导航时,控制器不会保留数据

如何将控制器上的选定数据存储到数据存储中,以便在其他控制器之间使用?

选项1-自定义
服务
您可以利用专用的angular服务在控制器之间存储和共享数据(是单实例对象)

服务定义

 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']
// ...
阅读

$window.localStorage['my-data'] = 'hello world';
var data = $window.localStorage['my-data']
// ...
  • 看看这个很棒的项目:

选项3-通过web服务器api 如果需要在不同用户之间持久化数据,则应将其保存在服务器端的某个位置(db/cache)


要在同一页面上的两个控制器之间共享数据,可以使用工厂/服务。举个例子来看

但是,如果是跨页面重新加载/刷新,则需要将数据存储在本地存储器中,然后在重新加载时读取数据。这里有一个例子:

编辑参见答案,他在其中撰写了一份深入的回复,涵盖了包括此方法在内的其他方法

我建议使用localStorage或sessionStorage-

HTML本地存储为在客户端上存储数据提供了两个对象:

  • window.localStorage-存储没有过期日期的数据
  • window.sessionStorage-存储一个会话的数据(关闭浏览器选项卡时数据丢失)
这假设您不想将数据发布/放置到web服务(问题中提到的windows服务)

如果您的数据是数组或某种类型的数据,则可以将其转换为JSON以字符串形式存储,然后在需要时可以按如下方式对其进行解析-:


有一个选项在其他答案(AFAIK)中未提及

事件

  • 可以使用事件在控制器之间进行通信

  • 这是一种直接的交流,不需要调解人 (如服务)并且不能被用户擦除(如HTML存储)

  • 所有代码都是在您尝试使用的控制器中编写的 与客户沟通,因此非常透明

下面是如何利用事件在控制器之间进行通信的一个很好的示例

发布者是想要发布的范围(换句话说,让别人知道发生了什么事)。大多数人不关心发生了什么,也不在这个故事中

订阅者关心某个事件是否已发布(换句话说,当它收到通知时,它会做出反应)

我们将使用$rootScope作为发布者和订阅者之间的中介。这始终有效,因为无论什么作用域发出事件,$rootScope都是该作用域的父级或父级的父级。。当$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;
      });

}]);
上面我们看到两个控制器使用事件相互传递消息。事件有一个名称,它必须是唯一的,否则订阅者不会区分事件。事件参数保存自动生成但有时有用的数据,消息是有效负载。在本例中,它是一个字符串,但可以是任何对象。因此,只需将所有希望通信的数据放在一个对象中,并通过事件发送即可

注意:

如果两个作用域位于彼此的直接继承行中,则可以避免为此目的使用根作用域(并限制收到事件通知的控制器的数量)。进一步解释如下:

$rootScope.$emit只允许其他$rootScope侦听器捕获它。当您不希望每个$scope都获得它时,这是很好的。主要是高层沟通。把它想象成成年人在房间里互相交谈,这样孩子们就听不见了

$rootScope.$broadcast是一种让几乎所有人都能听到的方法。这就相当于父母大喊晚餐准备好了,让家里的每个人都能听到

$scope.$emit是您希望该$scope及其所有父级和$rootScope听到事件的时间。这是一个孩子在家里(但不是在其他孩子都能听到的杂货店)向父母抱怨。这是一个快捷方式,当您希望从作为订阅服务器的子级或第n个子级的发布服务器进行通信时可以使用

$scope.$broadcast用于$scope本身及其子项。这是一个孩子对着玩具动物低声说话,这样他们的父母就听不见了

编辑:我认为plunker有一个更详细的例子就足够了,所以我决定在这里保持简单。这个详细的解释应该更好。

检查这个库


这可以帮助您更简单地管理应用程序状态,因为它将强制您在应用程序上使用单向数据流。

要添加到本地存储方法,可以使用
JSON.stringify(myData)
将其存储为字符串和
JSON.parse(localStorage['my-data'))
收回它-。完全同意。甚至建议使用这个很棒的项目:另一个选项是ngStorage,它通过注入服务$localstorage和$sessionstorage访问一个简单的api,以一种角度解决localstorage和sessionstorage问题-谢谢你的回复。如果我使用服务选项,UI会如何是否知道何时更新其视图?如果