-
25 Apr 2012 12:28 PM #1
Answered: Overload Ext.data.Store not working
Answered: Overload Ext.data.Store not working
Hi!
Here's what I've done (and it works): declare two functions:
And now create a store:Code:var fnStoreAfterWrite=function(proxy, operation) { Ext.example.msg( Ext.String.capitalize(operation.action), operation.resultSet.message ); }; var fnStoreException=function(proxy, response, operation) { var error=operation.getError(); if (error instanceof Array) { error=error.join("<br />"); } Ext.MessageBox.show({ title: 'Erreur du serveur', width: '50%', msg: error, icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); };
Look at the last lines of code: they call the functions. I wanted to overload Ext.data.Store this way:Code:var storeCategories = Ext.create('Ext.data.Store', { model: 'Intranet.Categorie', autoLoad: true, autoSync: true, proxy: { type: 'ajax', api: { read: 'xx', create: 'xx', update: 'xx', destroy: 'xx' }, reader: { type: 'json', successProperty: 'success', root: 'data', messageProperty: 'message' }, writer: new Ext.data.writer.Json( { type: 'json', writeAllFields: true, root: 'data' }), listeners: { exception: fnStoreException } }, listeners: { write: fnStoreAfterWrite } });
Code:Ext.define('Ext.data.StoreHandleErrors', { extend: 'Ext.data.Store', alias: 'widget.datastorehandleerrors', initComponent: function(){ this.callParent(); }, onStoreException: function(proxy, response, operation) { Ext.MessageBox.show({ title: 'Erreur du serveur', width: '50%', msg: operation.getError(), icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); }, onStoreAfterWrite: function(proxy, operation) { Ext.example.msg( Ext.String.capitalize(operation.action), operation.resultSet.message ); } });
And then do something like:
But it doesn't work, there's a JavaScript exception.Code:var storeCategories = Ext.create('Ext.data.StoreHandleErrors', { model: 'Intranet.Categorie', autoLoad: true, autoSync: true, proxy: { type: 'ajax', api: { read: 'xx', create: 'xx', update: 'xx', destroy: 'xx' }, reader: { type: 'json', successProperty: 'success', root: 'data', messageProperty: 'message' }, writer: new Ext.data.writer.Json( { type: 'json', writeAllFields: true, root: 'data' }), listeners: { exception: this.onStoreException } }, listeners: { write: this.onStoreAfterWrite } });
Any idea of what I'm doing wrong?
-
Best Answer Posted by olivierpons
Ok here's my whole code. I don't know if it's the right way to do it but it works, and it seems "generic" enough for me.
First part: create a descendant of Ext.data.Store, and create a "default config" even for its proxy:
Second part: how to use the class:Code:Ext.define('Ext.data.StoreHandleErrors', { extend: 'Ext.data.Store', alias: 'data.storehandleerrors', constructor: function(config) { /* (!!) override some proxy properties * (!!) if they exist they'll be overwritten */ config.autoLoad= true; config.autoSync= true; config.proxy.type= 'ajax'; config.proxy.reader= { type: 'json', successProperty: 'success', root: 'data', messageProperty: 'message' }; config.proxy.writer= { type: 'json', writeAllFields: true, root: 'data' }; config.proxy.listeners= { exception: function(proxy, response, operation) { var error=operation.getError(), title='Erreur du serveur'; if (error instanceof Array) { error=error.join(""); } switch(response.status) { case 200: if (response.responseText!='') { var b = Ext.JSON.decode(response.responseText); if (b.title) { title=b.title; } if (b.success==false) { if (b.timeout==true) { windowLoginPanel.show(); } } } break; case -1: var error= 'Le serveur met trop de temps à répondre'+ ' '+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; case 500: var error= 'Le serveur a une erreur interne.'+ ' '+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; default: var error= 'Erreur renvoyée par le serveur non gérée.'+ 'Détails :'+ response.statusText+ ' '+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; } Ext.MessageBox.show({ title: title, msg: error, icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); } }; this.callParent([config]); this.on( 'write', function(proxy, operation) { if ( (operation.action == 'create') || (operation.action == 'update') ) { var m = this.getById( parseInt( operation.resultSet.records[0].internalId ) ); } else if (operation.action == 'destroy') { var m = this.getAt(0); } if (m) { this.panelGridEtEdit.gsGrid.getSelectionModel().select(m); } else { this.panelGridEtEdit.gsGrid.getSelectionModel().deselectAll(); } Ext.example.msg( Ext.String.capitalize(operation.action), operation.resultSet.message ); }, this ); } });
Code:var storeAdresses = Ext.create('Ext.data.StoreHandleErrors', { model: 'Intranet.Adresse', proxy: { api: { read: '/json/intranet/liste/adresses/', create: '/json/intranet/item/adresse/?mode=create', update: '/json/intranet/item/adresse/?mode=update', destroy: '/json/intranet/item/adresse/?mode=destroy' } } });
-
25 Apr 2012 3:40 PM #2
At defining time of Ext.data.StoreHandleErrors, this points to window object (or some other object) and this object does not have onStoreException and onStoreAfterWrite methods.
Below is my suggestion to fix this problem:
Code:var storeCategories = Ext.create('Ext.data.StoreHandleErrors', { model: 'Intranet.Categorie', autoLoad: true, autoSync: true, proxy: { type: 'ajax', api: { read: 'xx', create: 'xx', update: 'xx', destroy: 'xx' }, reader: { type: 'json', successProperty: 'success', root: 'data', messageProperty: 'message' }, writer: new Ext.data.writer.Json( { type: 'json', writeAllFields: true, root: 'data' }), listeners: { exception: function(){ storeCategories.onStoreException.apply(storeCategories, arguments); } } }, listeners: { write: function(){ storeCategories.onStoreAfterWrite.apply(storeCategories, arguments) } } });
-
26 Apr 2012 12:59 AM #3
Thank you very much for your answer. The code you give works, but it's not "universal".
I'm working on making a universal "code".
Here's what I did: I've added a log, and it shows "this", so "this" shouldn't be a problem, and in the debug console I can see that the functions added to the class are ok and present:
So I'm trying another way, which work for another class: in the "initcomponent()" function add an event handler. Example of something that works flawlessly:Code:var storeAdresses = Ext.create('Ext.data.StoreHandleErrors', { ...blabla... listeners: { write: fnStoreAfterWrite, read: function(proxy, operation) { console.log(this); } } });
But initComponent() is never called in the code! I don't get that:Code:Ext.define('MasterDetail.form.Panel', { extend: 'Ext.form.Panel', alias: 'widget.masterdetailform', requires: ['Ext.form.field.Text'], initComponent: function(){ this.addEvents('create'); this.callParent(); this.on( 'validitychange', function(form, valid, eOpts) { if (valid) { this.down('#save').enable(); } else { this.down('#save').disable(); } }, this );
So, now, I'm definitely stuck on this. initComponent() should be called whichever class it is or is it just for specific classes?Code:Ext.define('Ext.data.StoreHandleErrors', { extend: 'Ext.data.Store', alias: 'widget.datastorehandleerrors', initComponent: function(){ console.log('--------------------------'); console.log(this); this.callParent(); },
-
26 Apr 2012 1:53 AM #4
\o/
Found it!
It seems the initComponent function is not called with Ext.data components.
But when examining the code, constructor is always called. I don't know if it's "safe" but it works pretty well.
Now I'll be able to override my proxy too and eventually add a listener to the "exception" event!
Code:Ext.define('Ext.data.StoreHandleErrors', { extend: 'Ext.data.Store', alias: 'widget.datastorehandleerrors', constructor: function(config) { this.callParent([config]); this.on( 'write', function(proxy, operation) { if ( (operation.action == 'create') || (operation.action == 'update') ) { ...code... } else if (operation.action == 'destroy') { ...code... } }, this ); }, ...code...
-
26 Apr 2012 6:00 AM #5
Ok here's my whole code. I don't know if it's the right way to do it but it works, and it seems "generic" enough for me.
First part: create a descendant of Ext.data.Store, and create a "default config" even for its proxy:
Second part: how to use the class:Code:Ext.define('Ext.data.StoreHandleErrors', { extend: 'Ext.data.Store', alias: 'data.storehandleerrors', constructor: function(config) { /* (!!) override some proxy properties * (!!) if they exist they'll be overwritten */ config.autoLoad= true; config.autoSync= true; config.proxy.type= 'ajax'; config.proxy.reader= { type: 'json', successProperty: 'success', root: 'data', messageProperty: 'message' }; config.proxy.writer= { type: 'json', writeAllFields: true, root: 'data' }; config.proxy.listeners= { exception: function(proxy, response, operation) { var error=operation.getError(), title='Erreur du serveur'; if (error instanceof Array) { error=error.join(""); } switch(response.status) { case 200: if (response.responseText!='') { var b = Ext.JSON.decode(response.responseText); if (b.title) { title=b.title; } if (b.success==false) { if (b.timeout==true) { windowLoginPanel.show(); } } } break; case -1: var error= 'Le serveur met trop de temps à répondre'+ ' '+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; case 500: var error= 'Le serveur a une erreur interne.'+ ' '+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; default: var error= 'Erreur renvoyée par le serveur non gérée.'+ 'Détails :'+ response.statusText+ ' '+ 'On ne peut rien faire, essayez '+ 'd\'actualiser la page.'; break; } Ext.MessageBox.show({ title: title, msg: error, icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); } }; this.callParent([config]); this.on( 'write', function(proxy, operation) { if ( (operation.action == 'create') || (operation.action == 'update') ) { var m = this.getById( parseInt( operation.resultSet.records[0].internalId ) ); } else if (operation.action == 'destroy') { var m = this.getAt(0); } if (m) { this.panelGridEtEdit.gsGrid.getSelectionModel().select(m); } else { this.panelGridEtEdit.gsGrid.getSelectionModel().deselectAll(); } Ext.example.msg( Ext.String.capitalize(operation.action), operation.resultSet.message ); }, this ); } });
Code:var storeAdresses = Ext.create('Ext.data.StoreHandleErrors', { model: 'Intranet.Adresse', proxy: { api: { read: '/json/intranet/liste/adresses/', create: '/json/intranet/item/adresse/?mode=create', update: '/json/intranet/item/adresse/?mode=update', destroy: '/json/intranet/item/adresse/?mode=destroy' } } });


Reply With Quote
