Sencha Touch - проблемы местного хранения - PullRequest
2 голосов
/ 17 февраля 2012

У меня есть несколько проблем с Sencha Touch и localstorage ...

1) Я могу сохранять данные в localalstorage, и он прекрасно работает, пока я не обновлю страницу.После этого я все еще могу получать доступ к данным, вносить изменения и даже добавлять новые записи.Но как только страница обновляется, все мои обновления исчезают.Все, что было добавлено, будет в порядке, но обновления оригинальных записей не будут сохранены (надеюсь, это имеет смысл).По сути, я могу создать запись и обновить все, что я хочу, пока я не обновлю страницу.В этот момент он не сохранится в местном хранилище снова.Новые записи всегда сохраняются нормально.

2) Когда я удаляю все записи своих записей, а затем обновляю страницу, я получаю эту ошибку в консоли: «Uncaught TypeError: Невозможно прочитать свойство 'id' из null".Похоже, что он пытается загрузить что-то, хотя там ничего нет.Я не уверен, почему это вызвало бы ошибку в этой ситуации, а не при первоначальной загрузке страницы, поскольку это должно быть то же самое, верно?

Модель:

    Ext.regModel('inventoryItem', {
        idProperty: 'id',
        fields: [
            { name: 'id', type: 'int' },
            { name: 'date', type: 'date', dateFormat: 'c' },
            { name: 'title', type: 'string' },
            { name: 'quantity', type: 'int' },
            { name: 'size', type: 'int' },
            { name: 'cost', type: 'double' },
            { name: 'startDate', type: 'date' },
            { name: 'endDate', type: 'date' },
            { name: 'dailyAvgCost', type: 'string' },
            { name: 'dailyAvgSize', type: 'string' }
        ]
    });

Магазин:

    Ext.regStore('inventoryItemsStore', {
        model: 'inventoryItem',
        sorters: [{
            property: 'id',
            direction: 'DESC'
        }],
        proxy: {
            type: 'localstorage',
            id: 'inventory-app-store'
        },
        getGroupString: function (record) {
            return '';
        }
    });

Обработчик:

     {
             var currentinventoryItem = CostsApp.views.inventoryEditor.getRecord();
             CostsApp.views.inventoryEditor.updateRecord(currentinventoryItem);
             var inventoryStore = CostsApp.views.inventoryList.getStore();
             if (null == inventoryStore.findRecord('id', currentinventoryItem.data.id))
             {
                     inventoryStore.add(currentinventoryItem);
             }

             inventoryStore.sync();
             inventoryStore.sort([{ property: 'date', direction: 'DESC'}]);
             CostsApp.views.inventoryList.refresh();
      }

Может кто-нибудь указать на очевидное, что я делаю неправильно

Ответы [ 6 ]

3 голосов
/ 15 октября 2012

У меня была та же проблема, и я переместил свой прокси в модель, и это решило мою проблему. Ваш измененный код должен выглядеть так:

Модель:

Ext.regModel('inventoryItem', {
    idProperty: 'id',
    fields: [
        { name: 'id', type: 'int' },
        { name: 'date', type: 'date', dateFormat: 'c' },
        { name: 'title', type: 'string' },
        { name: 'quantity', type: 'int' },
        { name: 'size', type: 'int' },
        { name: 'cost', type: 'double' },
        { name: 'startDate', type: 'date' },
        { name: 'endDate', type: 'date' },
        { name: 'dailyAvgCost', type: 'string' },
        { name: 'dailyAvgSize', type: 'string' }
    ],
proxy: new Ext.data.LocalStorageProxy({
    id: 'inventory-app-store'
})
});

Магазин:

Ext.regStore('inventoryItemsStore', {
    model: 'inventoryItem',
    sorters: [{
        property: 'id',
        direction: 'DESC'
    }],
    getGroupString: function (record) {
        return '';
    }
});
1 голос
/ 13 января 2013

Я знаю это старое, но, возможно, оно кому-нибудь поможет. У меня возникла та же проблема, и я попытался сбросить локальное хранилище window.localStorage.clear();, и оно работает.

1 голос
/ 28 сентября 2012

Это, вероятно, что-то еще.

Вы используете « id » в качестве имени ключа в полях модели, измените его на что-то еще, например « inventory_id », и повторите попытку.

У меня сложилось впечатление, что id используется внутри API локального хранилища, поэтому зарезервировано.

1 голос
/ 28 сентября 2012

Store sync () оказался очень сложным для меня, это может помочь пролить некоторый свет.

.sync() не будет обновлять записи удаленного локального хранилища, если они не загрязнены.Таким образом, они не будут постоянными.

С помощью считывателя типа json легко допустить ошибку непосредственного изменения записи, для этого нужно использовать методы Модели, в частности .set(), поскольку установлен() определяет запись как «грязную», и только тогда sync () фактически сохранит изменения.

Это особенно трудно отладить с использованием локального хранилища.

Для следующего магазина:

Ext.define('MyApp.store.LocalStuff',{
extend: 'Ext.data.Store',
xtype:'localstuff',

config: {
    fields:['stuffId','stuffName','stuffArray'],
    storeId:'LocalStuffId',
    autoLoad:false,
    proxy:{
        type:'localstorage',
        id:'idForLocalStorage',
        reader: {
            type: 'json',
            rootProperty: 'stuffArray'
        }
    }
}
});

Предполагая, что вы наполнили магазин чем-то вроде:

{'stuffArray':[
{'stuffId':'130',   'stuffName':'floob',    'stuffArray':[  
                                                            'first',
                                                            'second',
                                                            'tird' //here be a typo (on purpose)
                                                            ]
                                                        },
{'stuffId':'131',   'stuffName':'sateo',    'stuffArray':[  
                                                            'primero',
                                                            'segundo',
                                                            'tercero'
                                                            ]
                                                        },
{'stuffId':'133',   'stuffName':'tolus',    'stuffArray':[  
                                                            'prima',
                                                            'secunda',
                                                            'tertia'
                                                            ]
                                                        }
]
}

Чтобы исправить ошибку записи первой записи, у вас может возникнуть соблазн сделать следующее:

{//in a given controller or view
someEventHandler:function(){
    var stor = Ext.getStore('LocalStuffId');
    var firstRecord = stor.getAt(0);//which will get you a record in the form of a Model
    firstRecord.get('stuffArray')[2]='third';//that will fix it
    //now we just sync() to make the change persist when we close the app
    stor.sync();
}
}

Если вы попробовали это, на консоли не будет ошибок, так что все в порядке.Правильно?

Неверно!Изменения не сохранятся при перезапуске.Зачем?

Потому что записи «чистые».

Как мы можем «испачкать» их?

Единственный способ, который я нашел (я уверен, что их гораздо больше), - это использование метода .set () * 1033.* из модели, чтобы обновить запись, которая сообщит магазину, что она грязная

Это звучит странно для моего неподготовленного мозга на MVC, лучше исправить приведенный выше пример.

{//in a given controller or view
someEventHandler:function(){
    var stor = Ext.getStore('LocalStuffId');
    var firstRecord = stor.getAt(0);//which will get you a record in the form of a Model
    //you might go around the following 2 lines in many ways, the important part is .set() after that
    var theArrayToFix = firstRecord.get('stuffArray');
    theArrayToFix[2]='third';

    firstRecord.set('stuffArray',theArrayToFix);//set() dirties the record
    //NOW we sync() to make the change persist when we close the app
    stor.sync();
}
}

Все этоЭто может быть очевидно для кого-то, пришедшего с сенча touch 1, но для новичка, такого как я, это было близко к дневной работе, чтобы выяснить.

Надеюсь, это кому-нибудь поможет, это наверняка поможет мне в будущем.1041 *

0 голосов
/ 27 июля 2012

Как насчет вызова метода sync () перед условием if? У меня это сработало.

var inventoryStore = CostsApp.views.inventoryList.getStore();
inventoryStore.load();
inventoryStore.sync();
0 голосов
/ 29 марта 2012

Кажется, все выглядит хорошо - метод store.add() используется вместе с store.sync(). Проверьте, как вы загружаете данные в список, может быть, данные просто не загружены. Что касается меня, свойство autoload магазина работает не всегда (может быть, есть некоторые причины, я не отрицаю), и я просто использую store.load() вместо этого. Кроме того, вы можете проверить localStorage напрямую, чтобы точно определить это (то есть элемент идентификатора прокси localStorage.getItem('inventory-app-store') должен дать вам что-то вроде "1,2,3" - идентификаторы успешно сохраненных записей).

Вот рабочий пример, на всякий случай.

new Ext.Application({
    name: 'MyApp',
    launch: function() {
        this.viewport = new Ext.Panel({
            fullscreen: true,
            id    : 'mainPanel',
            layout: 'card',
            dockedItems: [{
                xtype: 'toolbar',
                dock : 'top',
                items: [{
                    xtype: 'textfield',
                    flex: 1
                }, {
                    text: 'Add',
                    listeners: {
                        tap: function () {
                            var view = this.viewport,
                                list = view.items.first(),
                                store = list.store,
                                fld = view.dockedItems.first().items.first(),
                                val = fld.getValue();
                            store.add({item: val});
                            store.sync();
                            fld.reset();
                        },
                        scope: this
                    }
                }]
            }],
            items : [{
                xtype: 'list',
                itemTpl : '{item}',
                store: new Ext.data.Store({
                    fields: ['item'],
                    proxy: {
                        id: 'items',
                        type: 'localstorage',
                    }
                }).load()
            }]
        });
    }
});
...