1

我正在尝试使用 2.2.1 制作一个基本的 Sencha Touch 应用程序,该应用程序将按照此示例脱机工作。到目前为止,我所拥有的或多或少是一些不同领域的直接克隆,并且在浏览器中运行良好。

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

我尝试过拥有 JSON 数据的本地副本,但这似乎并没有通过 存储在 iOS 上,cache.manifest所以这也不是一个后备选项。有没有办法让它在 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
    }
});
4

2 回答 2

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 设备上运行。

希望这是有道理的,快乐的编码。

于 2013-09-11T19:39:31.933 回答
1

尝试从Ext.Application创建两个商店,而不是:Ext.create('Ext.data.Store', {model: "MyApp.model.OfflineTable"})使用相同的模型并复制在线商店(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();
                });
            }
        }
    }
});

表本地:

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

那么您应该始终使用MyApp.store.TablesLocal.

希望能帮助到你-

于 2013-09-11T17:30:22.610 回答