PDA

View Full Version : How to add/update/delete record in writable store without passing changes to server



honzakuchar
16 Jul 2010, 2:21 AM
Hi ExtJS community :),
I'm working on some project, where I need to have writable store. User changes something, it is automatically passed to server... Nice!

But now I'm working on real-time live updates of store and I need, to apply changes in store, that did other user.
So in practical, user creates new record by calling
store.insert();. And about 10ms later, server send information to all clients, that row was inserted. And now what to call, to only add row to store and not to write it back to server.

Thank you very much for response,
Jan Kucha?

Animal
16 Jul 2010, 2:35 AM
http://www.sencha.com/deploy/dev/docs/?class=Ext.data.Store&member=autoSave

honzakuchar
16 Jul 2010, 2:42 AM
Thank you very much for response, but It is not solution for me.

Because when user makes some changes in store and new data from other users recieved and I will call store.save() manually, data will be also changed more than one time on server. I need something like to remove it from modified in store, or something like this. It is really hard to explain what I exactly need in English.

honzakuchar
17 Jul 2010, 1:18 AM
Sorry, after some analysis of sources, I found solution. So if someone needs it, here it is:


Ext.ns("Ext.ux.data");

Ext.ux.data.NetteLiveStore = Ext.extend(Ext.Nette.Store/* can be replaced with any other store */, {

/**
* Getts record by real id (real primary key, not phantom id)
* Workaround: When is record inserted into store, record will have some generated id.
* When record id updates, it is still unchanged in keys array
*/
getByRealId: function(id) {
// this = store
var d = this.data.items;
for(var y=0,l1=d.length; y<l1; y++) {
var r = d[y];
if(r.id == id) {
return r;
}
}
return undefined;
},

/* ---> These methods are used only for synchonization with database on server */

/**
* Call function when autoSave is off
*/
callFnAndSaveStoreState: function(fn,scope) {
// Save state
var orig = this.autoSave,
modified = [].concat(this.modified),
removed = [].concat(this.removed);
this.autoSave = false;

fn.call(scope);

// Restore state
this.autoSave = orig;
this.modified = modified;
this.removed = removed;
},


/**
* Delete record locally, it will be NEVER passed to server!
*/
locallyRemove: function(rec) {
this.callFnAndSaveStoreState(function(){
this.remove(rec);
},this);
},

/**
* Add record locally, it will be NEVER passed to server (event if store.save() called)!
*/
locallyAdd: function(rec) {
this.callFnAndSaveStoreState(function(){
this.add(rec);
},this);
},

locallyAddDoNotDuplicate: function(rec) {
// Check primary keys
if(typeof this.getByRealId(rec.id) !== "undefined") return false;

this.locallyAdd(rec);
return true;
},

locallyModifyRecord: function(recInStore, newData) {

var callFnAndSaveRecordState = function(fn,scope) {
/* this = Ext.data.Record */
var modified = Ext.isArray(this.modified) ? [].concat(this.modified) : [],
dirty = this.dirty,
editing = this.editing;

fn.call(scope);

this.dirty = dirty;
this.modified = modified;
this.editing = editing;
this.afterEdit();
}

this.callFnAndSaveStoreState(function() {
var fields = recInStore.fields.items;
callFnAndSaveRecordState.call(recInStore, function(){ // TODO: Do this only if field is not modified...
// Replace old data with new
for(var i=0, l=fields.length; i<l; i++) {
var name = fields[i].name;
if(typeof newData[name] === "undefined") continue;
recInStore.set(name,newData[name]);
}
}, this);
}, this);
},

/**
* Inser record locally, it will be NEVER passed to server (event if store.save() called)!
*/
locallyInsert: function(index, rec) {
this.callFnAndSaveStoreState(function(){
this.insert(index, rec);
//this.removeFromModified(rec);
},this);
}

/* <--- end of synchronization methods */

});

There is used some Nette.Store, it doesn't matter, use any other store you want. It is only copyied from our app. So thank you very much Animal! ;-)