- execute : function(action, rs, options, /* private */ batch) {
- // blow up if action not Ext.data.CREATE, READ, UPDATE, DESTROY
- if (!Ext.data.Api.isAction(action)) {
- throw new Ext.data.Api.Error('execute', action);
- }
- // make sure options has a fresh, new params hash
- options = Ext.applyIf(options||{}, {
- params: {}
- });
- if(batch !== undefined){
- this.addToBatch(batch);
- }
- // have to separate before-events since load has a different signature than create,destroy and save events since load does not
- // include the rs (record resultset) parameter. Capture return values from the beforeaction into doRequest flag.
- var doRequest = true;
-
- if (action === 'read') {
- doRequest = this.fireEvent('beforeload', this, options);
- Ext.applyIf(options.params, this.baseParams);
- }
- else {
- // if Writer is configured as listful, force single-record rs to be [{}] instead of {}
- // TODO Move listful rendering into DataWriter where the @cfg is defined. Should be easy now.
- if (this.writer.listful === true && this.restful !== true) {
- rs = (Ext.isArray(rs)) ? rs : [rs];
- }
- // if rs has just a single record, shift it off so that Writer writes data as '{}' rather than '[{}]'
- else if (Ext.isArray(rs) && rs.length == 1) {
- rs = rs.shift();
- }
- // Write the action to options.params
- if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
- this.writer.apply(options.params, this.baseParams, action, rs);
- }
- }
- if (doRequest !== false) {
- // Send request to proxy.
- if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
- options.params.xaction = action; // <-- really old, probaby unecessary.
- }
- // Note: Up until this point we've been dealing with 'action' as a key from Ext.data.Api.actions.
- // We'll flip it now and send the value into DataProxy#request, since it's the value which maps to
- // the user's configured DataProxy#api
- // TODO Refactor all Proxies to accept an instance of Ext.data.Request (not yet defined) instead of this looooooong list
- // of params. This method is an artifact from Ext2.
- this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
- }
- return doRequest;
- },
-
- /**
- * Saves all pending changes to the store. If the commensurate Ext.data.Api.actions action is not configured, then
- * the configured <code>{@link #url}</code> will be used.
- * <pre>
- * change url
- * --------------- --------------------
- * removed records Ext.data.Api.actions.destroy
- * phantom records Ext.data.Api.actions.create
- * {@link #getModifiedRecords modified records} Ext.data.Api.actions.update
- * </pre>
- * @TODO: Create extensions of Error class and send associated Record with thrown exceptions.
- * e.g.: Ext.data.DataReader.Error or Ext.data.Error or Ext.data.DataProxy.Error, etc.
- * @return {Number} batch Returns a number to uniquely identify the "batch" of saves occurring. -1 will be returned
- * if there are no items to save or the save was cancelled.
- */
- save : function() {
- if (!this.writer) {
- throw new Ext.data.Store.Error('writer-undefined');
- }
-
- var queue = [],
- len,
- trans,
- batch,
- data = {};
- // DESTROY: First check for removed records. Records in this.removed are guaranteed non-phantoms. @see Store#remove
- if(this.removed.length){
- queue.push(['destroy', this.removed]);
- }
-
- // Check for modified records. Use a copy so Store#rejectChanges will work if server returns error.
- var rs = [].concat(this.getModifiedRecords());
- if(rs.length){
- // CREATE: Next check for phantoms within rs. splice-off and execute create.
- var phantoms = [];
- for(var i = rs.length-1; i >= 0; i--){
- if(rs[i].phantom === true){
- var rec = rs.splice(i, 1).shift();
- if(rec.isValid()){
- phantoms.push(rec);
- }
- }else if(!rs[i].isValid()){ // <-- while we're here, splice-off any !isValid real records
- rs.splice(i,1);
- }
- }
- // If we have valid phantoms, create them...
- if(phantoms.length){
- queue.push(['create', phantoms]);
- }
-
- // UPDATE: And finally, if we're still here after splicing-off phantoms and !isValid real records, update the rest...
- if(rs.length){
- queue.push(['update', rs]);
- }
- }
- len = queue.length;
- if(len){
- batch = ++this.batchCounter;
- for(var i = 0; i < len; ++i){
- trans = queue[i];
- data[trans[0]] = trans[1];
- }
- if(this.fireEvent('beforesave', this, data) !== false){
- for(var i = 0; i < len; ++i){
- trans = queue[i];
- this.doTransaction(trans[0], trans[1], batch);