在iOS上的Sencha Touch离线后退

时间:2013-09-11 14:30:57

标签: sencha-touch sencha-touch-2 local-storage offline-caching cache-manifest

我正在尝试使用2.2.1创建一个基本的Sencha Touch应用程序,该应用程序将在this example之后脱机工作。到目前为止,我所拥有的东西或多或少是一个不同领域的直接克隆,它在浏览器中运行良好。

例如,在Chrome上,我可以看到存储到localStorage的项目,如果我关闭计算机的互联网连接,则会将其读入。但是在iOS上,我尝试将应用程序保存到主屏幕,并且在连接时效果很好。但是,当我将设备置于飞行模式后,localStorage似乎为空,我的列表显示为空。

我已尝试使用JSON数据的本地副本,但似乎并未通过cache.manifest存储在iOS上,因此这也不是后备选项。有没有办法让这个在iOS上的浏览器/主屏幕上工作?谢谢。

更新缓存的密钥控制器代码如下(注意它与上面的示例匹配,但某些不同的模型/商店名称除外):

    init: function () {
        var onlineStore = Ext.getStore('Tables'),
        localStore = Ext.create('Ext.data.Store', {
            model: "MyApp.model.OfflineTable"
        }),
        me = this;

        localStore.load();

        /*
        * When app is online, store all the records to HTML5 local storage.
        * This will be used as a fallback if app is offline more
        */
        onlineStore.on('refresh', function (store, records) {
            // Get rid of old records, so store can be repopulated with latest details
            localStore.getProxy().clear();

            store.each(function(record) {
                var rec = {
                    id: record.data.id,
                    text: record.data.text,
                    content: record.data.content,
                    group: record.data.group
                };
                localStore.add(rec);
                localStore.sync();
            });
            console.log("Setting local store of size " + localStore.getCount());
            console.log("Item 0 is " + localStore.getAt(0).data.text);
        });

        /*
        * If app is offline a Proxy exception will be thrown. If that happens then use
        * the fallback / local stoage store instead
        */
        onlineStore.getProxy().on('exception', function () {
            me.getTables().setStore(localStore); //rebind the view to the local store
            console.log("Getting local store of size " + localStore.getCount());
            console.log("Item 0 is " + localStore.getAt(0).data.text);
            localStore.each(function(record) {
                console.log(record);
            });
            localStore.load(); // This causes the "loading" mask to disappear
            Ext.Msg.alert('Notice', 'You are in offline mode', Ext.emptyFn); //alert the user that they are in offline mode
        });
    }

来自上面的console.log来电,我可以看到我的localStorage在浏览器和连接时看起来很棒,但在iOS上断开连接后仍然是空的(尽管在桌面上离线仍然很好)。

我的离线型号是:

Ext.define('MyApp.model.OfflineTable', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            "id",
            "text",
            "content",
            "group"
        ],
        identifier:'uuid', // needed to avoid console warnings!
        proxy: {
            type: 'localstorage',
            id: 'offlineTableData'
        }
    }
});

我的在线模型只是

Ext.define('MyApp.model.Table', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            "id",
            "text",
            "content",
            "group"
        ]
    }
});

最后我的商店是:

Ext.define('MyApp.store.Tables', {
    extend: 'Ext.data.Store',

    config: {
        model: 'MyApp.model.Table',
        proxy: {
            timeout: 3000,
            type: 'ajax',
            url: /* DATA URL */
        },
        autoLoad: true
    }
});

2 个答案:

答案 0 :(得分:1)

尝试使用相同的模型从 Ext.Application 而不是:Ext.create('Ext.data.Store', {model: "MyApp.model.OfflineTable"})创建两个商店,并复制在线商店(TablesRemote)加载回调中的内容:

TablesRemote:

Ext.define('MyApp.store.TablesRemote', {
    extend: 'Ext.data.Store',

    config: {
        model: 'MyApp.model.Table',
        proxy: {
            timeout: 3000,
            type: 'ajax',
            url: /* DATA URL */
        },
        autoLoad: true,

        listeners: {
            load: function(st, g, s, o, opts) {
                var localStore = Ext.getStore('TablesLocal');
                st.each(function(record) {
                    localStore.add(record);
                    localStore.sync();
                });
            }
        }
    }
});

TablesLocal:

Ext.define('MyApp.store.TablesLocal', {
    extend: 'Ext.data.Store',
    config: {
        model: 'MyApp.model.Table',
        proxy: {
            type: 'localstorage'
        },
        autoLoad: true
    }
});

然后,您应始终使用MyApp.store.TablesLocal访问数据。

希望有所帮助 -

答案 1 :(得分:1)

稍后几个小时的调试我终于找到了一个有效的解决方案。对于Sencha Touch如何处理localStorage,有一个完全(据我所见)无证的细微差别。我遵循的原始样本的想法是将在线数据同步到本地商店,以便以后使用:

store.each(function(record) {
    var rec = {
        id: record.data.id,
        text: record.data.text,
        content: record.data.content,
        group: record.data.group
    };
    localStore.add(rec);
    localStore.sync();
});

然而在实践中,这仅将数据本地存储在当前实例中,从而使得该点失败。 Sencha实际上只更新了浏览器的“脏”记录的本地存储。由于我们正在制作全新的唱片,因此他们吱吱作响“干净”。因此,为了实现localStore.sync()调用,我们需要在上面的复制循环中弄脏我们的记录,如下所示:

store.each(function(record) {
    var myRecord = Ext.create("MyApp.model.Table", {
        id: record.data.id,
        text: record.data.text,
        group: record.data.group,
        content: record.data.content
    });
    myRecord.setDirty();
    theStore.add(myRecord);
    theStore.sync();
});

本质上,我们根据我们的全局表模型创建一个“脏”记录,并将其添加到本地存储,然后正确地同步和存储它,因为它现在“脏”。这将每条记录存储为单独的localStorage属性,原始offlineTableData(在我们的模型的代理ID中声明)显然用作所有条目的ID索引。因此,您会在offlineTableData中看到一大堆localStorage个条目,但不会烦恼;我不确定是否有办法压缩这个,但它似乎在初始同步后在飞机模式的iOS设备上工作。

希望有意义,快乐的编码。