【问题标题】:Rethinking data structure using LocalStorage and AngularJS使用 LocalStorage 和 AngularJS 重新思考数据结构
【发布时间】:2015-12-15 13:53:39
【问题描述】:

我使用 LocalStorage 构建了一个应用程序。

它将大量对象存储在一个键下,我最近发现这是阻止 DOM 的原因,因为应用程序必须在每次我阅读或写入“数据库”。

引用answer from another question

由于 LocalStorage 和 JSON stringify/parse 都在主线程上同步发生,它可能会阻塞 DOM 渲染,从而降低您的应用程序的速度。

数据插入如下:

$scope.recordlist = extractRecordJSONFromLocalStorage();
$scope.addRecord = function () {
    $scope.recordlist.push(
            {
                date: $scope.dateJson, 
                time: $scope.time, 
                car: $scope.carList.code, 
                driver: $scope.driverList.name,
                from: $scope.locationList.place,
                destination: $scope.locationList2.place, 
                pax: $scope.paxList,
                comments: [],
                arrival: '',
                inserted: '',
                cancelled:'',
                duration:''
            }
        );
    jsonToRecordLocalStorage($scope.recordlist);
};

既然如此,我需要重新思考我存储和阅读它的整个方式。

这种方式对我来说很有意义,因为我使用 AngularJS 来读取、过滤和比较存储在这个单一键中的对象。

<div class="row msf-row" 
     ng-repeat="record in filteredRecords = (recordlist | filter:dateFilter | filter: search )" 
     ng-hide="is.cancelled && (!record.cancelled || record.cancelled === '') || has.comment && (!record.comment || record.comment === '')" 
     ng-class="{ 'msf-cancelled': record.cancelled, 'msf-commented' : record.comment}" 
     ng-hide="!record.arrival && !record.cancelled" 
     ng-show="record.cancelled">

关于如何将其迁移到哪个系统以及为什么迁移的任何提示?

我想保留 AngularJS 的功能。那么如果我不是每次都读取整个文件,我该如何过滤记录呢?

你可以看到working example of the app here

我意识到我缺少关于数据存储和读取方式的关键概念。除了直接答案之外,任何指向有关该问题的文档/理论的提示也将受到高度赞赏。

【问题讨论】:

  • 我看到了你的应用。而且我看到您正在本地存储中保存每一个汽车时刻。既然你的是单页应用程序,为什么不简单地 ajax 发布数据并将记录保存在服务器端?
  • 2 ng-hide 和 ng-show 在你的中继器上没有意义,而且会制造太多手表
  • @brute_force 它应该是一个离线应用程序!我可以使用 LS 作为“服务器端”吗?

标签: javascript json angularjs local-storage


【解决方案1】:

一项改进可能是将 ng-show 和 ng-hide 指令替换为用于显示数据的自定义过滤器。

angular.module('myapp', []).filter('showhide', function() {

    return function(record, isCancelled) {

        var hide1 = isCancelled && (!record.cancelled || record.cancelled === '') || has.comment && (!record.comment || record.comment === '');

        var hide2 = !record.arrival && !record.cancelled;

        return !hide1 && !hide2;
    };
});

并像这样称呼它

<div class="row msf-row" 
     ng-repeat="record in filteredRecords = (recordlist | filter:dateFilter | filter: search | showhide:is.cancelled )" 
     ng-class="{ 'msf-cancelled': record.cancelled, 'msf-commented' : record.comment}">

这取决于要加载到 javascript 变量中并由您的脚本过滤的所有数据。我假设您的数据不是那么大,因为这会导致问题,例如列表中不超过 10000 个对象。 DOM 性能更多的是关于真正渲染了多少项目。每个 ng-hide 元素实际上都会被渲染,然后会再次从列表中删除。

然后,您必须将此列表存储在变量中的某个位置,该变量只能读取一次,并且只能将更新写入 localstorage 对象。您可以通过使用保存您的数据的服务来做到这一点。

angular.module('myapp', []).service('dataService', function() {

    var data = ... // get from localStorage
    return {
        get: data,
        save: function(){
            // put the variable 'data' to localStorage
        }
    }
}

然后在您的控制器中进行操作

angular.module('myapp').controller('myCtrl', function($scope, dataService){
    $scope.recordList = dataService.get();
});

从那里您可以修改数组而无需再次读取它,如果您对数组进行了任何更新,您可以在 dataService 对象上调用 save()。

另一种选择是使用 pouchdb 或 dexie.js 之类的东西,并创建一个服务来设置所有过滤器并直接查询数据库。如果要将数据同步到 couchdb 实例,则 pouchdb 很好。如果您只想将数据存储在客户端中,dexie.js 可能会更容易。

但我不认为你的 localStorage 解决方案发展得这么快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多