PDA

View Full Version : Delaying store update to server?



neilios
18 Dec 2011, 12:36 PM
Using Ext-JS 4.
I'd like to delay a store's server update until after I've made a set of changes so that it sends all the changes at once.

I've tried 2 ways to do this, and neither seems to work:

1/ Set autoSync to false in the Store and catch "datachanged" or "update" events and call sync() when I want to
However, I could not get the events to fire after performing a set() on a Store's record. Here's the config used for the Store:


return {
extend: 'Ext.data.Store',
requires: 'MVRZ.model.'+name,
model: 'MVRZ.model.'+name,
storeId: datasetId,
autoLoad: autoLoad,
//autoSync: true,
autoSync: false, // Do this explicitly
sorters: sortArray,
pageSize: pageSize,
listeners: [
{
eventName: "datachanged",
fn: function(store, eOpts) {
MVRZ.Dataset.setDirty(store.storeId);
}
},{
eventName: "update",
fn: function(store, record, operation, eOpts) {
MVRZ.Dataset.setDirty(store.storeId);
}
}
]
};


I tried the "other" way of setting the listeners too:


listeners: [
{
datachanged: function(store, eOpts) {
MVRZ.Dataset.setDirty(store.storeId);
},
update: function(store, record, operation, eOpts) {
MVRZ.Dataset.setDirty(store.storeId);
}
}
]




Here's the code used to update the store (it's photo re-ordering from a dataview drag-n-drop):


onNodeDrop : function(target, dd, e, data){
var insertBeforeId = view.getRecord(target).getId();
var dr = data.draggedRecord;
var draggedId = dr.getId();

// Change position values
var nodes = view.getNodes();
var started = false;
var position = 1;
var store = view.getStore();


Ext.each(nodes, function(node, index) {
var r = view.getRecord(node);
var id = r.getId();

if(!started && id != draggedId && id != insertBeforeId) {
position++;
return;
}
if(id == insertBeforeId) { // First time, found item to insert before
dr.set('position', position++);
r.set('position', position++);
} else if(id != draggedId) {
r.set('position', position++);
}
started = true;
});
store.sort();
return true;
}





... the Store events are never fired.


2/ Keep autoSync as true and stop the store from saving using suspendEvents()


onNodeDrop : function(target, dd, e, data){
var insertBeforeId = view.getRecord(target).getId();
var dr = data.draggedRecord;
var draggedId = dr.getId();

// Change position values
var nodes = view.getNodes();
var started = false;
var position = 1;
var store = view.getStore();
store.suspendEvents(false); // Wait until all changes are made before updating any server records
Ext.each(nodes, function(node, index) {
var r = view.getRecord(node);
var id = r.getId();

if(!started && id != draggedId && id != insertBeforeId) {
position++;
return;
}
if(id == insertBeforeId) { // First time, found item to insert before
dr.set('position', position++);
r.set('position', position++);
} else if(id != draggedId) {
r.set('position', position++);
}
started = true;
});
store.sort();
store.resumeEvents();
store.sync();
return true;
}



... the store still saves each record in turn. In fact, it issues saves with increasing numbers of changes (the last one has all changes) as it happens so quickly.


What is the right way to do this? Is there a bug with the events here?

Thanks

tobiu
19 Dec 2011, 4:17 AM
what shall this be?


MVRZ.Dataset.setDirty(store.storeId);


if you are using the update event, the record (model) that got updated is passed as an argument. you can call setDirty() on a record (no param!):
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model-method-setDirty

but your record should already be flagged. you can call record.commit() though.

neilios
19 Dec 2011, 10:35 AM
what shall this be?


MVRZ.Dataset.setDirty(store.storeId);


if you are using the update event, the record (model) that got updated is passed as an argument. you can call setDirty() on a record (no param!):
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model-method-setDirty

but your record should already be flagged. you can call record.commit() though.

setDirty() is my function (coincidentally the same name as the Model function). I would manage updates using this - allowing me to turn off synchronization if I wanted to.

However, the problem is that it never gets called - the event it never triggered.

Thanks

neilios
21 Dec 2011, 11:45 AM
I worked around the issue of the events not getting fired by setting up the same events during onLaunch of the controller using the store's "on" method. I can now turn off autoSync and do a sync when I want to.

Seems like the events do not get created correctly during initialization of the store - not sure if that is a bug or the way it's meant to be.