From 7a963412c02f0b382f30d83c4fb94f98901a5437 Mon Sep 17 00:00:00 2001 From: Marco Celotti Date: Tue, 13 Oct 2015 13:17:49 +0200 Subject: [PATCH] Once a new record has been saved to local db, the phantom property is set to false, as a consequence when you sync with server the phantom property is still false and the POST url has the record id in the path (ie POST /model/ext-record-123) which is wrong. This is the fix to this problem. --- Ext.ux.OfflineSyncStore-min-debug.js | 37 ++++++++++++++++++++++------ Ext.ux.OfflineSyncStore-min.js | 2 +- Ext.ux.OfflineSyncStore.js | 37 ++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/Ext.ux.OfflineSyncStore-min-debug.js b/Ext.ux.OfflineSyncStore-min-debug.js index 703a120..2f6428a 100644 --- a/Ext.ux.OfflineSyncStore-min-debug.js +++ b/Ext.ux.OfflineSyncStore-min-debug.js @@ -134,7 +134,7 @@ Ext.define('Ext.ux.OfflineSyncStore', { * @private * @returns {void} */ - onBatchComplete: function(batch) { + onBatchComplete : function(batch) { this.callParent(arguments); if (this.isLocalMode()) { this.fireEvent('localsynccomplete', this, batch); @@ -142,10 +142,11 @@ Ext.define('Ext.ux.OfflineSyncStore', { this.syncServer(); } } else { + this.resetPhantomForCreatedRecords(batch); this.fireEvent('remotesynccomplete', this, batch); } }, - + /** * This is called once the batch operation failed. * We do nothign special here, we just fire event to notify exception. @@ -153,13 +154,29 @@ Ext.define('Ext.ux.OfflineSyncStore', { * @private * @returns {void} */ - onBatchException: function(batch, operation) { + onBatchException : function(batch, operation) { this.callParent(arguments); - var event = 'remotesyncexception'; if (this.isLocalMode()) { - event = 'localsyncexception'; + this.fireEvent('localsyncexception', this, batch, operation); + } else { + this.resetPhantomForCreatedRecords(batch); + this.fireEvent('remotesyncexception', this, batch, operation); } - this.fireEvent(event, this, batch, operation); + }, + + /** + * This method is used to reset phantom for created records once the batch is completed + * @private + * @returns {void} + */ + resetPhantomForCreatedRecords : function(batch) { + Ext.each(batch.operations, function(operation) { + if (operation.getAction() === "create") { + Ext.each(operation.getRecords(), function(record) { + record.phantom = false; + }, this); + } + }, this); }, /** @@ -187,7 +204,13 @@ Ext.define('Ext.ux.OfflineSyncStore', { // This is required so the store can map up the returned records to the ones in the store to update IDs etc. // When we do a local save a new ID gets generated for the record which we don't want to send to the server. for(var i = 0; i < toCreate.length; i++){ - toCreate[i].data[this.getModel().getIdProperty()] = toCreate[i].id; + var record = toCreate[i]; + record.data[this.getModel().getIdProperty()] = record.id; + + // Once a new record has been saved to local db, the phantom property is set to false. + // As a consequence when we sync with server the phantom property is still false and the POST url has the id in the path (ie POST /model/ext-record-123) and this is wrong. + // Therefore we force phantom to be true (phantom is set back to false in "resetPhantomForCreatedRecords") + record.phantom = true; } operations.create = toCreate; diff --git a/Ext.ux.OfflineSyncStore-min.js b/Ext.ux.OfflineSyncStore-min.js index b779d1b..7c1d682 100644 --- a/Ext.ux.OfflineSyncStore-min.js +++ b/Ext.ux.OfflineSyncStore-min.js @@ -1,4 +1,4 @@ /* * Ext.ux.OfflineSyncStore */ -Ext.define("Ext.ux.OfflineSyncStore",{extend:"Ext.data.Store",config:{trackLocalSync:true,autoServerSync:true,localProxy:null,serverProxy:null},statics:{CREATED:"created",UPDATED:"updated",REMOVED:"removed"},constructor:function(a){a=a||{};this.callParent([a])},loadLocal:function(a,b){this._proxy=this.getLocalProxy();this.load(a,b,true)},loadServer:function(a,b){this._proxy=this.getServerProxy();this.on({load:{fn:this.onServerLoad,single:true,scope:this}});this.load(a,b,true)},sync:function(){this._proxy=this.getLocalProxy();var d=this.callParent(arguments);var c=d.added,a=d.updated,b=d.removed;if(this.getTrackLocalSync()){if(c.length>0){this.storeCreated(c)}if(a.length>0){this.storeUpdated(a)}if(b.length>0){this.storeRemoved(b)}}return d},onBatchComplete:function(a){this.callParent(arguments);if(this.isLocalMode()){this.fireEvent("localsynccomplete",this,a);if(this.doAutoServerSync()){this.syncServer()}}else{this.fireEvent("remotesynccomplete",this,a)}},onBatchException:function(b,a){this.callParent(arguments);var c="remotesyncexception";if(this.isLocalMode()){c="localsyncexception"}this.fireEvent(c,this,b,a)},syncServer:function(){this._proxy=this.getServerProxy();var e=this,b={},f=e.getModifiedRecordsCollection(Ext.ux.OfflineSyncStore.CREATED),d=e.getModifiedRecordsCollection(Ext.ux.OfflineSyncStore.UPDATED),a=e.getRemovedRecordsCollection(Ext.ux.OfflineSyncStore.REMOVED),g=false;if(f.length>0){for(var c=0;c0){b.update=d;g=true}if(a.length>0){b.destroy=a;g=true}if(g&&e.fireEvent("beforesync",this,b)!==false){e.getProxy().batch({operations:b,listeners:e.getBatchListeners()})}return{added:f,updated:d,removed:a}},storeCreated:function(a){this.storeChanged(a,Ext.ux.OfflineSyncStore.CREATED,false)},storeUpdated:function(d){var g=this.getModifiedCollection(Ext.ux.OfflineSyncStore.CREATED),e=[],k=[],a=false,h=this.getModel().getIdProperty();for(var c=0;c0},hasPendingUpdated:function(){return this.getModifiedCollection(Ext.ux.OfflineSyncStore.UPDATED).length>0},hasPendingRemoved:function(){return this.getModifiedCollection(Ext.ux.OfflineSyncStore.REMOVED).length>0},doAutoServerSync:function(){var a=this.getAutoServerSync();if(Ext.isFunction(a)){a=a.call(this)}return a},applyServerProxy:function(b,a){return this.applyProxy(b,a)},updateServerProxy:function(a){this.updateProxy(a)},applyLocalProxy:function(b,a){return this.applyProxy(b,a)},updateLocalProxy:function(a){this.updateProxy(a)},mergeOrReplaceArrays:function(g,f,b){var e=0,c=g.length,a=f.length,h=false;b=b||this.getModel().getIdProperty();for(;e0){this.storeCreated(c)}if(a.length>0){this.storeUpdated(a)}if(b.length>0){this.storeRemoved(b)}}return d},onBatchComplete:function(a){this.callParent(arguments);if(this.isLocalMode()){this.fireEvent("localsynccomplete",this,a);if(this.doAutoServerSync()){this.syncServer()}}else{this.resetPhantomForCreatedRecords(a);this.fireEvent("remotesynccomplete",this,a)}},onBatchException:function(b,a){this.callParent(arguments);if(this.isLocalMode()){this.fireEvent("localsyncexception",this,b,a)}else{this.resetPhantomForCreatedRecords(b);this.fireEvent("remotesyncexception",this,b,a)}},resetPhantomForCreatedRecords:function(a){Ext.each(a.operations,function(b){if(b.getAction()==="create"){Ext.each(b.getRecords(),function(c){c.phantom=false},this)}},this)},syncServer:function(){this._proxy=this.getServerProxy();var f=this,c={},g=f.getModifiedRecordsCollection(Ext.ux.OfflineSyncStore.CREATED),e=f.getModifiedRecordsCollection(Ext.ux.OfflineSyncStore.UPDATED),b=f.getRemovedRecordsCollection(Ext.ux.OfflineSyncStore.REMOVED),h=false;if(g.length>0){for(var d=0;d0){c.update=e;h=true}if(b.length>0){c.destroy=b;h=true}if(h&&f.fireEvent("beforesync",this,c)!==false){f.getProxy().batch({operations:c,listeners:f.getBatchListeners()})}return{added:g,updated:e,removed:b}},storeCreated:function(a){this.storeChanged(a,Ext.ux.OfflineSyncStore.CREATED,false)},storeUpdated:function(d){var g=this.getModifiedCollection(Ext.ux.OfflineSyncStore.CREATED),e=[],k=[],a=false,h=this.getModel().getIdProperty();for(var c=0;c0},hasPendingUpdated:function(){return this.getModifiedCollection(Ext.ux.OfflineSyncStore.UPDATED).length>0},hasPendingRemoved:function(){return this.getModifiedCollection(Ext.ux.OfflineSyncStore.REMOVED).length>0},doAutoServerSync:function(){var a=this.getAutoServerSync();if(Ext.isFunction(a)){a=a.call(this)}return a},applyServerProxy:function(b,a){return this.applyProxy(b,a)},updateServerProxy:function(a){this.updateProxy(a)},applyLocalProxy:function(b,a){return this.applyProxy(b,a)},updateLocalProxy:function(a){this.updateProxy(a)},mergeOrReplaceArrays:function(g,f,b){var e=0,c=g.length,a=f.length,h=false;b=b||this.getModel().getIdProperty();for(;e