【问题标题】:How do I reset a collection in Titanium Alloy?如何重置钛合金中的收藏?
【发布时间】:2013-10-21 09:42:29
【问题描述】:

Backbonejs 集合具有reset a collection 用于批量更新的功能。当我与来自服务器的 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 时,同步的数据就消失了,并且替换为默认数据。

【问题讨论】:

  • 你找到解决办法了吗?
  • 不,我没有 - 我停止尝试了。

标签: jasmine titanium-mobile titanium-alloy


【解决方案1】:

我发现的最佳方法(我很遗憾不记得我从哪里复制代码)是手动进行重置。我发布了执行此操作的代码:https://gist.github.com/sukima/8321859

基本上我自己做 SQL DELETE 然后是 Backbone reset(),然后循环 INSERT INTO,最后完成一个主干 trigger("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");
    };

  }

};

【讨论】:

  • 这会在 Alloy > 1.3 上中断,因为新合金不包含 alloy/sync/util.js 模块。我不知道为什么。 :'(
  • 那么如果alloy/sync/util.js 模块失败,还有什么替代方案呢?使用外部 db 文件是唯一的出路吗?
  • @anish,我不知道,因此“我不知道为什么”评论。我愚蠢地希望比我更聪明的人愿意启发我们其他人。
  • util.js的内容是:function S4() { return (0 | 65536 * (1 + Math.random())).toString(16).substring(1); } exports.guid = function() { return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4(); };所以可以将上面的代码复制到我们的模块中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
相关资源
最近更新 更多