View Full Version : DirectStore callback from save?

11 May 2009, 3:44 PM
Because Ext.Direct writes in the background after a timeout, I am perplexed about how to do the following:

1) A user clicks a button to save a form.
2) The button click triggers store.loadData({jsonRoot: form.getValues()})
3) DirectStore automatically writes the record and receives a success code
4) The success of the write triggers a callback to close the form,

My question is: where do I pass this callback to close the window? I am trying to fully integrate my old Ext JS 2.0 app with 3.0, for learning purposes. I know I could use the automatically generated Model.save() function to save the data but I want the store to be updated at the same time.

How do I callback from the save?



13 May 2009, 5:39 AM
In current SVN code Ext.data.Store has a 'write' event. That gets fired when a save, create or destroy action was performed. Older RCs had distinct 'save', 'create' and 'destroy' events.

E.g. this is code from one app I already Ext.Direct'ed to handle server validation errors. I'm optimistic and close the form right away. Only when a validation error occurs the form pops up again with the erroneous record.

initComponent: function() {
// ...
this.store = new Ext.data.GroupingStore({
// ...
listeners: {
write: this.onStoreWrite,
writeexception: this.onStoreWriteException,
load: this.onLoad,
loadexception: this.onLoadException,
scope: this
// ...
showForm: function(record){
if (!this.form) {
this.formRecord = record;
this.valueRecordBinder.setRecord(record); // custom plugin that keeps form fields and record in sync
// ...
commitEdit: function(){
if (this.form.formpanel.getForm().isValid()) {
var r = this.formRecord;
this.formRecord = null;
r.endEdit(); // if r is not new, this will trigger a update via the writer
if (!r.store) {
this.store.add(r); // this will trigger a create
else {
// some fancy validation error notification
// ...
onStoreWrite: function(store, action, result, transaction, rs){
console.log('onwrite', store, action, result, transaction, rs);
if (!transaction.status) {
this.showForm(Ext.isArray(rs) ? rs[0] : rs);
// some fancy validation error notification

13 May 2009, 7:35 AM
Yeah this is the conclusion I came to, that you would have to subscribe to Direct's create, save and destroy events.

The problem is that you have no guarantee that the next write event will be from your form. In many cases you might be able to rely on this code without a guarantee, but not always. For instance, if your form does two writes to the server -- or maybe to two different servers -- and one succeeds while another fails, how do you know which one failed?

A real-world example could be a form where the user adds the information about an author, and then enters titles for all his books. The author might be sent to one url, and books to another.

This might seem contrived but really, without these kinds of guarantees our apps just skating by on coincidence. This seems like a decidedly inferior solution compared to what we were doing before Ext.Direct: having our forms receive the response from the server directly and decide from that how to proceed.

Perhaps we need something like an Ext.DirectForm which would return a non-phantom record that is ready for insertion to a store.

13 May 2009, 7:51 AM
I meant the create, update and destroy events of the Store (or, the write event in newer builds)

These events are only fired for this particular store. No ambiguity there with other Ext.Direct stuff. There is however an ambiguity when you create records for this store in another way than through this form. You could e.g. use a single-shot event listener (@cfg single:true) for the write event if that's the case.

function onWrite(store, action, result, transaction, rs){
store.un('writeexception', onWriteException, this); // remove the other listener that was not fired
if (transaction.status) {
} else {
// error handling
function onWriteException() {
store.un('write', onWrite, this); // remove the other listener that was not fired
// error handling

store.on('write', onWrite, this, { single:true } );
store.on('writeexception', onWriteException, this, { single:true } );
store.loadData({jsonRoot: form.getValues()});

13 May 2009, 8:04 AM
Okay so subscribe to the DirectStore instead of Ext.Direct. I think that's better.

It still limits you to only one way of creating records, which is probably ok. Plus you still have to engineer your app in such a way that when your user clicks submit, the very next write event must result from your record create attempt.

But then you also don't get to use the cool features of a Form, like the automatic determination of success and failure based on the success property returned from the server. Also you have to manually invoke client-side validation. All this stuff was wrapped up within the Submit action which is not Direct-friendly.

Perhaps I will write a DirectForm class that can be associated with a DirectStore, if one is not already in the works.

Thanks for your response!