使用LocalStorage和AngularJS重新思考数据结构

时间:2015-09-18 12:04:43

标签: javascript json angularjs local-storage

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

它在单个密钥下存储大量对象,我最近发现这是阻止DOM的原因,因为应用程序每次读取时都必须进行JSON解析/字符串化并存储/检索整个列表。写信给“数据库”。

引用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

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

1 个答案:

答案 0 :(得分: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解决方案。