Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExtJS 4.2: Multiple Inserts

Ok, so say I have a store server side so we are doing remote everything. Example of stores:

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

I hit a problem when I do the following:

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

What happens is that when I look at the DB I end up having 2 entries. I get 'hi' once and 'say' twice. From the looks of it what is happening is that the first insert statement gets sent and then the second insert statement gets sent but with data from both inserts (I assume it's cause they share the same model and thus the same proxy)

Thoughts on how I can resolve this so that it doesn't auto merge insertion requests?

Model for your viewing pleasure:

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'
    }
}
});
like image 663
Aram Papazian Avatar asked Dec 06 '25 06:12

Aram Papazian


1 Answers

I think you are not returning the correct data from the server side on the create. If you do not return the id the server created on the first insert, ExtJS will still think your "say" item is a phantom. That is, it has not yet been stored server side.

When you do the second insert, the store will do a sync as you have autosync on. Sync will send ALL pending changes. Since your "hi" item is new that will be sent in a POST as is expected. But since your previous "hi" item does not have a server generated id and is still a phantom, it too will be sent in a POST with your second sync (triggered by the insert).

Basically the server must return the new id with the success result set so that ExtJS knows that the item has been stored by the server. Here's an example from my REST API:

Request has this payload (check Chrome Developer tools network tab).

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

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

This is the server response (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
}

All fields in the model are updated by the data in the server response, and as such your hi and say items will get their server id's set. When the id is set, the phantom property is set to false. You can have a look in the Ext.data.Model js-file for the source code for this if you want to dig deeper. :)

In your case you must have idContact in the returned object as that is you idProperty.

If you want to suspend auto sync, do your inserts and sync manually and then turn auto syncs back on you can use SuspendAutoSync and ResumeAutoSync.

The best way to add models to stores in my opinion is to create your model, save it, and on success put it in the store. That requires you to have the proxy in each model. That would look something like this:

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

In this way you could add your second item in the success handler of the first item's save.

like image 112
oldwizard Avatar answered Dec 09 '25 14:12

oldwizard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!