1

Backbonejs コレクションには、一括更新のためにコレクションをリセットする機能があります。サーバーからの JSON データと同期するときに Titanium Alloy でこの機能を使用したいのですが、これが SQLite にコミット/保存されていないように見えます - SQL アダプターを使用しています。

config: {
        columns: {
            // stuff
            name: "TEXT"
        },
        adapter: {
            type: "sql",
            collection_name: "pony",
            db_name: Alloy.CFG.db_name
        }
    }

失敗し続けるジャスミンテストがいくつかあります。参考までに、コレクションに7つのアイテムを追加する開発用の移行スクリプトを用意して、何か作業できるようにしました。

describe("pony model", function () {
    var Alloy = require("alloy")
            data = {name: "My little pony"},
        collection,
        item;

    beforeEach(function(){
        collection = Alloy.createCollection('pony');
        item = Alloy.createModel('pony');
    });

    // PASSES
    it('can reset all data', function () {
        collection.fetch();
        expect(collection.length).toEqual(7);

        collection.reset(data)
        expect(collection.length).toEqual(1);
     })

     // FAILS
     it('saves reset data', function () {
        collection.fetch();
        expect(collection.length).toEqual(7);

        collection.reset(data)
        collection.fetch()
        expect(collection.length).toEqual(1);
     })

     afterEach(function () {
         item.destroy();
     });
})

このバグがUIに表示される方法は、サーバーとデータを同期するときにそれを保存すると、TableViewに新しいレコードが表示され、別のビューに移動して同じTableViewに戻ると、同期されたデータがなくなり、デフォルトデータ。

4

1 に答える 1

3

私が見つけた最善の方法は (恥ずかしながらコードをどこからコピーしたのか思い出せません)、手動でリセットすることでした。これを行うためのコードを投稿しました: https://gist.github.com/sukima/8321859

基本的に、私は独自の SQL を実行し、次にDELETEBackboneを実行しreset()、次に loopedを実行しINSERT INTO、最後に backbonetrigger("fetch")イベントで終了します。バックボーンの同期を介してこれを行うと、速度が遅くなります。とにかく、通常reset()は同期を実行しません。

exports.definition = {

  config: {
    columns: {
      // ...
    },
    adapter: {
      type:            "sql",
      collection_name: "MyModels"
    }
  },

  extendCollection: function(Collection) {

    Collection.prototype.destroyAll = function(opt) {
      var db = Ti.Database.open(this.config.adapter.db_name);
      db.execute("DELETE FROM " + this.config.adapter.collection_name);
      db.close();
      this.models = [];
      if (!opt || !opt.silent) { this.trigger("reset"); }
      return this;
    };

    Collection.prototype.saveAll = function(opt) {
      var util    = require("alloy/sync/util");
      var dbName  = this.config.adapter.db_name;
      var table   = this.config.adapter.collection_name;
      var columns = this.config.columns;
      var db      = Ti.Database.open(dbName);

      db.execute("BEGIN;");

      this.forEach(function (model) {
        if (!model.id) {
          model.id = util.guid();
          model.attributes[model.idAttribute ] = model.id;
        }
        var names = [], values = [], q = [];
        for (var k in columns) {
          names.push(k);
          values.push(model.get(k));
          q.push("?");
        }
        var sqlInsert = "INSERT INTO " + table + " (" + names.join(",") + ") VALUES (" + q.join(",") + ");";

        db.execute(sqlInsert, values);
      });

      db.execute("COMMIT;");
      db.close();

      if (!opt || !opt.silent) { this.trigger("reset"); }
      return this;
    };

    Collection.prototype.refreshFromData = function refreshFromData(data) {
      this.destroyAll({silent:true});
      this.reset(data, {silent:true});
      this.saveAll({silent: true});
      this.trigger("fetch");
    };

  }

};
于 2014-01-08T18:45:19.410 に答える