1

Я пытаюсь создать базовое приложение Sencha Touch с 2.2.1, которое будет работать в автономном режиме после this example. То, что я до сих пор, является более или менее прямым клоном этого с некоторыми разными полями, и он отлично работает в браузере.Sencha Touch Offline Fallback on iOS

В 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 
    } 
}); 

ответ

1

Попробуйте создать оба магазина от Ext. Приложение вместо: 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.

Надежда это helps-

+0

Так что мне нужны два магазина для локального/онлайн? Пример, который я выполнил в моем исходном вопросе, использовал две модели с онлайн-магазином, а затем создал локальное хранилище в файле контроллера, как указано выше. – Primus202

+0

Да, я знаю. IMO мнение лучше и более MVC образом. Я много использую этот подход и никогда не испытывал никаких проблем, это очень контролируемое решение. –

+0

Пробовал, но это просто простая структура. Я думаю, что я отследил свою проблему: обновления, которые я делал в моем магазине localStorage, на самом деле не были сохранены. Sencha только синхронизирует «грязные» записи в 'sync'. Теперь я вижу свои данные, хранящиеся в 'localStorage', через инспектора, но я должен выяснить, как его прочитать. – Primus202

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 (как указано в прокси-идентификаторе нашей модели), видимо, служащим индексом идентификатора для всех записей. Таким образом, вы увидите целую цепочку из offlineTableData записей в localStorage, но не волнуйтесь, я не уверен, есть ли способ сконденсировать это, но он, похоже, работает на устройстве iOS в режиме полета после первоначального sy пс.

Надеюсь, что имеет смысл, счастливое кодирование.