3

好的,假设我有一个商店服务器端,所以我们正在远程做所有事情。店铺示例:

   Ext.create('Ext.data.Store', {
        model: 'MyApp.model.ContactModel',
        remoteFilter: true, 
        remoteSort: true,
        autoLoad: true,
        autoSync: true,
        storeId: 'ContactStore-1'
    });
   Ext.create('Ext.data.Store', {
        model: 'MyApp.model.ContactModel',
        remoteFilter: true, 
        remoteSort: true,
        autoLoad: true,
        autoSync: true,
        storeId: 'ContactStore-2'
    });

当我执行以下操作时遇到问题:

Ext.getStore('ContactStore-1').insert(0,{'name':'say'});
Ext.getStore('ContactStore-2').insert(0,{'name':'hi'});

发生的情况是,当我查看数据库时,我最终有 2 个条目。我会“嗨”一次,“说”两次。从它的外观来看,发生的事情是第一个插入语句被发送,然后第二个插入语句被发送,但是来自两个插入的数据(我认为这是因为它们共享相同的模型,因此具有相同的代理)

关于如何解决这个问题以便它不会自动合并插入请求的想法?

供您观赏的模型:

Ext.define('MyApp.model.ContactModel', {
extend: 'Ext.data.Model',

idProperty: 'idContact',

fields: [
    {
        name: 'idContact',
        type: 'int'
    },
    {
        name: 'name',
        type: 'string'
    }
],

proxy: {
    type: 'direct',
    api: {
        create: contact.createRecord,
        read: contact.getResults,
        update: contact.updateRecords,
        destroy: contact.destroyRecord
},
    reader: {
        type: 'json',
        root: 'data'
    }
}
});
4

1 回答 1

1

我认为您在创建时没有从服务器端返回正确的数据。如果您没有返回服务器在第一次插入时创建的 id,ExtJS 仍然会认为您的“说”项是phantom. 也就是说,它还没有被存储在服务器端。

当您进行第二次插入时,商店将在您开启自动同步时进行同步。同步将发送所有挂起的更改。由于您的“嗨”项目是新的,将按预期在 POST 中发送。但是由于您之前的“hi”项目没有服务器生成的 id 并且仍然是幻像,因此它也将与您的第二次同步(由插入触发)在 POST 中发送。

基本上,服务器必须返回带有成功结果集的新 id,以便 ExtJS 知道该项目已被服务器存储。这是我的 REST API 中的一个示例:

请求具有此有效负载(检查 Chrome 开发人员工具网络选项卡)。

POST to http://localhost:8081/api/channel?_dc=1372594759864

{"id":0,"number":0,"name":"test"}

这是服务器响应(200 OK):

{
  "result": {
    "id": 4, // <- important
    "number": 3,
    "name": "test",
  },
  "success": true,
  "location": "http://localhost:8081/api/item/4",
  "userMessage": null,
  "userTitle": "Success",
  "devErrors": null
}

模型中的所有字段都由服务器响应中的数据更新,因此您的 hi 和 say 项目将获得它们的服务器 ID 集。设置 id 时,幻像属性设置为 false。如果您想深入挖掘,可以查看 Ext.data.Model js 文件的源代码。:)

在您的情况下,您必须idContact在返回的对象中拥有 idProperty。

如果要暂停自动同步,请手动执行插入和同步,然后重新打开自动同步,您可以使用SuspendAutoSyncResumeAutoSync

在我看来,将模型添加到商店的最佳方式是创建模型,保存它,然后将其放入商店。这要求您在每个模型中都有代理。看起来像这样:

var hi = Ext.create('MyApp.model.ContactModel', {
    name: 'hi'
});

hi.save({
    success: function (record, operation) {
        Ext.getStore('ContactStore-1').add(hi);
        // You could do your second insert here that is dependent on the first to be completed
    },
    failure: function (record, operation) {
        Ext.MessageBox.alert("Error", "Could not save model at this time...");
    },
    scope: this
});

通过这种方式,您可以在第一项保存的成功处理程序中添加您的第二项。

于 2013-06-30T12:25:12.520 回答