PDA

View Full Version : insert on Store does not fire create URL



kumar_Rajesh78
24 Feb 2014, 11:15 AM
Dear experts,
I have two grids associated with two different stores.
My requirement is to remove the record from one store and put it into another.
I am writing the following code to do this.

store1.remove(selected);
store1.commitChanges();
//Add to Exception Store
store2.insert(0,selected);

This fires the destroy url configured for store1, but it does not fire the create URL for store2.

What could be the reason?

Thanks a lot.

Rajesh

kumar_Rajesh78
24 Feb 2014, 12:03 PM
I am iin the process of converting Extjs3 code to extjs 4.
In version 3, I had to use the following code to fix it, I guess.


data.iid=-1;
//record = new store.recordType(data);
//record.id = Ext.data.Record.id(record);
store.insert(0,[record]);


However, i dont find any equivalent way to achieve this in ExtJs4. the RecordType is no longer supported.

skirtle
24 Feb 2014, 1:56 PM
If you dig into the source code for sync you'll find it calls getNewRecords, which calls filterNew. This doesn't check for added records, only phantoms.

In my own applications I tend to override certain methods on stores to keep track of newly added, non-phantom records that I want to be saved by sync. If, instead, you'd like to try a quick fix you could just set the phantom flag to true.

kumar_Rajesh78
24 Feb 2014, 2:08 PM
Hi Skirtle,
If I look at the source code, my getNewRecords() does not call the filterNew method.
It just returns the empty array like this.


getNewRecords: function() { return []; },

Do you have a different version of the source code. If you, could you please paste that here.

Thanks,
Rajesh

skirtle
24 Feb 2014, 2:25 PM
That's in AbstractStore. It's overridden in Store.

kumar_Rajesh78
24 Feb 2014, 2:34 PM
Hi Skirtle,
First of all, thanks for answering my question.
You have mentioned about overriding the sync method or setting the phantom to true.
I would like to know, how do you do that.

Can we write a function within myStore.js file.
This is how I have defined my store.


Ext.define('Report.store.LeverageExceptions', {
extend: 'Ext.data.Store',
itemId: 'myItem',
autoLoad: true,
autoSync: true,
proxy: {
type:'ajax',
api: {
read:'/read',
create: '/abc',
},
headers: { 'Content-Type': 'application/json'},
actionMethods: {
create : 'GET',
read : 'GET',
update : 'GET'
//destroy: 'POST'
},
reader: {
type: 'json',
//idProperty: 'id',
//successProperty: 'success',
root: 'myRoot'
// messageProperty: 'message'
},
writer: {
encode: true,
type: 'json',
writeAllFields: true,
root: 'myRoot'
}
}
});


Thanks,
Rajesh

skirtle
24 Feb 2014, 2:45 PM
To set phantom to true it's just:


selected.phantom = true;

If you want to go down the other route you'd need to keep track of an array of records to be added and return them in getNewRecords. There isn't an easy method override to do the tracking so I tend to use the add and remove events instead. You'd also need to override sync to reset the array of records so it's only saved once.

One reason I tend to avoid the phantom hack is that my records are often shared between many stores, so they each need to track which records have been added. The phantom flag could be picked up by any store, not just the one it was added to.

kumar_Rajesh78
24 Feb 2014, 2:49 PM
Hi Skirtle,
Do we override these functions defined within ext-all-debug.js file.
If we do that there, then it would be applicable to all the stores.
And also, for Production, i will have to modify the production version of ext-all-debug.js file.

Do you override these methods somewhere else. such as within the store definition file.

Thanks,
Rajesh

kumar_Rajesh78
24 Feb 2014, 4:59 PM
unfortunately setting up phantom = true behaves very randomly.
I am actually selecting multiple records on grid and moving to another grid on another tab.
So I am doing something like this.


Ext.each(selections, function(selected, index){
var data = selected.data;
store1.remove(selected);
store1.commitChanges();
selected.phantom = true;
//Add to Exception Store
store.insert(0, selected);
});

but by doing this, during subsequent calls, the items keep on getting added. So in the first call to 'create', it passes one item, in the second it passes 2 items and in the third, it passes 3 items.

It should only pass one item in each call or make just one call with all the 3 items.

Any suggestions would be extremely helpful and appreciated most.

Thanks,
Rajesh

skirtle
25 Feb 2014, 12:18 AM
Do we override these functions defined within ext-all-debug.js file.

No, you should never change the contents of the ext*.js files. For bug patching you'd use an override using Ext.define and the override option. However, in your case you should just use a subclass.


during subsequent calls, the items keep on getting added

You could either explicitly remove them from the selection model or you could check they aren't already added before adding them.

kumar_Rajesh78
25 Feb 2014, 9:17 AM
I am overriding my function like this. I have put the following override in the same class as my Store definition.

Ext.override('Ext.data.Store', {
filterNew: function(item) {
console.log('hi');
// only want phantom records that are valid
return true;
}
});


This never gets called when I execute store.insert(0, selected). Shall I define it somewhere else?

skirtle
25 Feb 2014, 10:20 AM
Ideally you should override this method on a subclass rather than changing Store itself.

filterNew is called during syncing, not during insertion. If you are syncing and it still isn't hitting that code I would suggest that the code isn't being loaded for some reason.

kumar_Rajesh78
25 Feb 2014, 11:47 AM
I have set the autoSync to true. As per my understanding that should fire the sync event at insert.
Is that wrong understanding.

Thanks,
Rajesh

kumar_Rajesh78
25 Feb 2014, 12:02 PM
well,
I found a workaround for solving the phantom related issue.
This is what I did. I reset the phantom to false, once I did the insert.


Ext.each(selections, function(selected, index){
//Add to Exception Store
selected.phantom = true;
store.insert(0,selected);
selected.phantom = false;
});

skirtle
25 Feb 2014, 12:09 PM
I have set the autoSync to true. As per my understanding that should fire the sync event at insert.

sync is a method, not an event.

Take a look at the source for insert. The sync method will be called if autoSync is true and if at least one of the records being inserted is phantom.