| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 | <!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>
 |