<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js"><span id='Ext-data-Operation'>/** </span> * @author Ed Spencer * * Represents a single read or write operation performed by a {@link Ext.data.proxy.Proxy Proxy}. Operation objects are * used to enable communication between Stores and Proxies. Application developers should rarely need to interact with * Operation objects directly. * * Several Operations can be batched together in a {@link Ext.data.Batch batch}. */ Ext.define('Ext.data.Operation', { <span id='Ext-data-Operation-cfg-synchronous'> /** </span> * @cfg {Boolean} synchronous * True if this Operation is to be executed synchronously. This property is inspected by a * {@link Ext.data.Batch Batch} to see if a series of Operations can be executed in parallel or not. */ synchronous: true, <span id='Ext-data-Operation-cfg-action'> /** </span> * @cfg {String} action * The action being performed by this Operation. Should be one of 'create', 'read', 'update' or 'destroy'. */ action: undefined, <span id='Ext-data-Operation-cfg-filters'> /** </span> * @cfg {Ext.util.Filter[]} filters * Optional array of filter objects. Only applies to 'read' actions. */ filters: undefined, <span id='Ext-data-Operation-cfg-sorters'> /** </span> * @cfg {Ext.util.Sorter[]} sorters * Optional array of sorter objects. Only applies to 'read' actions. */ sorters: undefined, <span id='Ext-data-Operation-cfg-groupers'> /** </span> * @cfg {Ext.util.Grouper[]} groupers * Optional grouping configuration. Only applies to 'read' actions where grouping is desired. */ groupers: undefined, <span id='Ext-data-Operation-cfg-start'> /** </span> * @cfg {Number} start * The start index (offset), used in paging when running a 'read' action. */ start: undefined, <span id='Ext-data-Operation-cfg-limit'> /** </span> * @cfg {Number} limit * The number of records to load. Used on 'read' actions when paging is being used. */ limit: undefined, <span id='Ext-data-Operation-cfg-batch'> /** </span> * @cfg {Ext.data.Batch} batch * The batch that this Operation is a part of. */ batch: undefined, <span id='Ext-data-Operation-cfg-params'> /** </span> * @cfg {Object} params * Parameters to pass along with the request when performing the operation. */ <span id='Ext-data-Operation-cfg-callback'> /** </span> * @cfg {Function} callback * Function to execute when operation completed. * @cfg {Ext.data.Model[]} callback.records Array of records. * @cfg {Ext.data.Operation} callback.operation The Operation itself. * @cfg {Boolean} callback.success True when operation completed successfully. */ callback: undefined, <span id='Ext-data-Operation-cfg-scope'> /** </span> * @cfg {Object} scope * Scope for the {@link #callback} function. */ scope: undefined, <span id='Ext-data-Operation-property-started'> /** </span> * @property {Boolean} started * The start status of this Operation. Use {@link #isStarted}. * @readonly * @private */ started: false, <span id='Ext-data-Operation-property-running'> /** </span> * @property {Boolean} running * The run status of this Operation. Use {@link #isRunning}. * @readonly * @private */ running: false, <span id='Ext-data-Operation-property-complete'> /** </span> * @property {Boolean} complete * The completion status of this Operation. Use {@link #isComplete}. * @readonly * @private */ complete: false, <span id='Ext-data-Operation-property-success'> /** </span> * @property {Boolean} success * Whether the Operation was successful or not. This starts as undefined and is set to true * or false by the Proxy that is executing the Operation. It is also set to false by {@link #setException}. Use * {@link #wasSuccessful} to query success status. * @readonly * @private */ success: undefined, <span id='Ext-data-Operation-property-exception'> /** </span> * @property {Boolean} exception * The exception status of this Operation. Use {@link #hasException} and see {@link #getError}. * @readonly * @private */ exception: false, <span id='Ext-data-Operation-property-error'> /** </span> * @property {String/Object} error * The error object passed when {@link #setException} was called. This could be any object or primitive. * @private */ error: undefined, <span id='Ext-data-Operation-property-actionCommitRecordsRe'> /** </span> * @property {RegExp} actionCommitRecordsRe * The RegExp used to categorize actions that require record commits. */ actionCommitRecordsRe: /^(?:create|update)$/i, <span id='Ext-data-Operation-property-actionSkipSyncRe'> /** </span> * @property {RegExp} actionSkipSyncRe * The RegExp used to categorize actions that skip local record synchronization. This defaults * to match 'destroy'. */ actionSkipSyncRe: /^destroy$/i, <span id='Ext-data-Operation-method-constructor'> /** </span> * Creates new Operation object. * @param {Object} config (optional) Config object. */ constructor: function(config) { Ext.apply(this, config || {}); }, <span id='Ext-data-Operation-method-commitRecords'> /** </span> * This method is called to commit data to this instance's records given the records in * the server response. This is followed by calling {@link Ext.data.Model#commit} on all * those records (for 'create' and 'update' actions). * * If this {@link #action} is 'destroy', any server records are ignored and the * {@link Ext.data.Model#commit} method is not called. * * @param {Ext.data.Model[]} serverRecords An array of {@link Ext.data.Model} objects returned by * the server. * @markdown */ commitRecords: function (serverRecords) { var me = this, mc, index, clientRecords, serverRec, clientRec, i, len; if (!me.actionSkipSyncRe.test(me.action)) { clientRecords = me.records; if (clientRecords && clientRecords.length) { if (clientRecords.length > 1) { // If this operation has multiple records, client records need to be matched up with server records // so that any data returned from the server can be updated in the client records. If we don't have // a clientIdProperty specified on the model and we've done a create, just assume the data is returned in order. // If it's an update, the records should already have an id which should match what the server returns. if (me.action == 'update' || clientRecords[0].clientIdProperty) { mc = new Ext.util.MixedCollection(); mc.addAll(serverRecords); for (index = clientRecords.length; index--; ) { clientRec = clientRecords[index]; serverRec = mc.findBy(me.matchClientRec, clientRec); // Replace client record data with server record data clientRec.copyFrom(serverRec); } } else { for (i = 0, len = clientRecords.length; i < len; ++i) { clientRec = clientRecords[i]; serverRec = serverRecords[i]; if (clientRec && serverRec) { me.updateRecord(clientRec, serverRec); } } } } else { // operation only has one record, so just match the first client record up with the first server record this.updateRecord(clientRecords[0], serverRecords[0]); } if (me.actionCommitRecordsRe.test(me.action)) { for (index = clientRecords.length; index--; ) { clientRecords[index].commit(); } } } } }, updateRecord: function(clientRec, serverRec) { // if the client record is not a phantom, make sure the ids match before replacing the client data with server data. if(serverRec && (clientRec.phantom || clientRec.getId() === serverRec.getId())) { clientRec.copyFrom(serverRec); } }, // Private. // Record matching function used by commitRecords // IMPORTANT: This is called in the scope of the clientRec being matched matchClientRec: function(record) { var clientRec = this, clientRecordId = clientRec.getId(); if(clientRecordId && record.getId() === clientRecordId) { return true; } // if the server record cannot be found by id, find by internalId. // this allows client records that did not previously exist on the server // to be updated with the correct server id and data. return record.internalId === clientRec.internalId; }, <span id='Ext-data-Operation-method-setStarted'> /** </span> * Marks the Operation as started. */ setStarted: function() { this.started = true; this.running = true; }, <span id='Ext-data-Operation-method-setCompleted'> /** </span> * Marks the Operation as completed. */ setCompleted: function() { this.complete = true; this.running = false; }, <span id='Ext-data-Operation-method-setSuccessful'> /** </span> * Marks the Operation as successful. */ setSuccessful: function() { this.success = true; }, <span id='Ext-data-Operation-method-setException'> /** </span> * Marks the Operation as having experienced an exception. Can be supplied with an option error message/object. * @param {String/Object} error (optional) error string/object */ setException: function(error) { this.exception = true; this.success = false; this.running = false; this.error = error; }, <span id='Ext-data-Operation-method-hasException'> /** </span> * Returns true if this Operation encountered an exception (see also {@link #getError}) * @return {Boolean} True if there was an exception */ hasException: function() { return this.exception === true; }, <span id='Ext-data-Operation-method-getError'> /** </span> * Returns the error string or object that was set using {@link #setException} * @return {String/Object} The error object */ getError: function() { return this.error; }, <span id='Ext-data-Operation-method-getRecords'> /** </span> * Returns the {@link Ext.data.Model record}s associated with this operation. For read operations the records as set by the {@link Ext.data.proxy.Proxy Proxy} will be returned (returns `null` if the proxy has not yet set the records). * For create, update, and destroy operations the operation's initially configured records will be returned, although the proxy may modify these records' data at some point after the operation is initialized. * @return {Ext.data.Model[]} */ getRecords: function() { var resultSet = this.getResultSet(); return this.records || (resultSet ? resultSet.records : null); }, <span id='Ext-data-Operation-method-getResultSet'> /** </span> * Returns the ResultSet object (if set by the Proxy). This object will contain the {@link Ext.data.Model model} * instances as well as meta data such as number of instances fetched, number available etc * @return {Ext.data.ResultSet} The ResultSet object */ getResultSet: function() { return this.resultSet; }, <span id='Ext-data-Operation-method-isStarted'> /** </span> * Returns true if the Operation has been started. Note that the Operation may have started AND completed, see * {@link #isRunning} to test if the Operation is currently running. * @return {Boolean} True if the Operation has started */ isStarted: function() { return this.started === true; }, <span id='Ext-data-Operation-method-isRunning'> /** </span> * Returns true if the Operation has been started but has not yet completed. * @return {Boolean} True if the Operation is currently running */ isRunning: function() { return this.running === true; }, <span id='Ext-data-Operation-method-isComplete'> /** </span> * Returns true if the Operation has been completed * @return {Boolean} True if the Operation is complete */ isComplete: function() { return this.complete === true; }, <span id='Ext-data-Operation-method-wasSuccessful'> /** </span> * Returns true if the Operation has completed and was successful * @return {Boolean} True if successful */ wasSuccessful: function() { return this.isComplete() && this.success === true; }, <span id='Ext-data-Operation-method-setBatch'> /** </span> * @private * Associates this Operation with a Batch * @param {Ext.data.Batch} batch The batch */ setBatch: function(batch) { this.batch = batch; }, <span id='Ext-data-Operation-method-allowWrite'> /** </span> * Checks whether this operation should cause writing to occur. * @return {Boolean} Whether the operation should cause a write to occur. */ allowWrite: function() { return this.action != 'read'; } }); </pre> </body> </html>