<!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-proxy-Proxy'>/**
|
</span> * @author Ed Spencer
|
*
|
* Proxies are used by {@link Ext.data.Store Stores} to handle the loading and saving of {@link Ext.data.Model Model}
|
* data. Usually developers will not need to create or interact with proxies directly.
|
*
|
* # Types of Proxy
|
*
|
* There are two main types of Proxy - {@link Ext.data.proxy.Client Client} and {@link Ext.data.proxy.Server Server}.
|
* The Client proxies save their data locally and include the following subclasses:
|
*
|
* - {@link Ext.data.proxy.LocalStorage LocalStorageProxy} - saves its data to localStorage if the browser supports it
|
* - {@link Ext.data.proxy.SessionStorage SessionStorageProxy} - saves its data to sessionStorage if the browsers supports it
|
* - {@link Ext.data.proxy.Memory MemoryProxy} - holds data in memory only, any data is lost when the page is refreshed
|
*
|
* The Server proxies save their data by sending requests to some remote server. These proxies include:
|
*
|
* - {@link Ext.data.proxy.Ajax Ajax} - sends requests to a server on the same domain
|
* - {@link Ext.data.proxy.JsonP JsonP} - uses JSON-P to send requests to a server on a different domain
|
* - {@link Ext.data.proxy.Rest Rest} - uses RESTful HTTP methods (GET/PUT/POST/DELETE) to communicate with server
|
* - {@link Ext.data.proxy.Direct Direct} - uses {@link Ext.direct.Manager} to send requests
|
*
|
* Proxies operate on the principle that all operations performed are either Create, Read, Update or Delete. These four
|
* operations are mapped to the methods {@link #create}, {@link #read}, {@link #update} and {@link #destroy}
|
* respectively. Each Proxy subclass implements these functions.
|
*
|
* The CRUD methods each expect an {@link Ext.data.Operation Operation} object as the sole argument. The Operation
|
* encapsulates information about the action the Store wishes to perform, the {@link Ext.data.Model model} instances
|
* that are to be modified, etc. See the {@link Ext.data.Operation Operation} documentation for more details. Each CRUD
|
* method also accepts a callback function to be called asynchronously on completion.
|
*
|
* Proxies also support batching of Operations via a {@link Ext.data.Batch batch} object, invoked by the {@link #batch}
|
* method.
|
*/
|
Ext.define('Ext.data.proxy.Proxy', {
|
alias: 'proxy.proxy',
|
alternateClassName: ['Ext.data.DataProxy', 'Ext.data.Proxy'],
|
|
requires: [
|
'Ext.data.reader.Json',
|
'Ext.data.writer.Json'
|
],
|
|
uses: [
|
'Ext.data.Batch',
|
'Ext.data.Operation',
|
'Ext.data.Model'
|
],
|
|
mixins: {
|
observable: 'Ext.util.Observable'
|
},
|
|
<span id='Ext-data-proxy-Proxy-cfg-batchOrder'> /**
|
</span> * @cfg {String} batchOrder
|
* Comma-separated ordering 'create', 'update' and 'destroy' actions when batching. Override this to set a different
|
* order for the batched CRUD actions to be executed in. Defaults to 'create,update,destroy'.
|
*/
|
batchOrder: 'create,update,destroy',
|
|
<span id='Ext-data-proxy-Proxy-cfg-batchActions'> /**
|
</span> * @cfg {Boolean} batchActions
|
* True to batch actions of a particular type when synchronizing the store. Defaults to true.
|
*/
|
batchActions: true,
|
|
<span id='Ext-data-proxy-Proxy-cfg-defaultReaderType'> /**
|
</span> * @cfg {String} defaultReaderType
|
* The default registered reader type. Defaults to 'json'.
|
* @private
|
*/
|
defaultReaderType: 'json',
|
|
<span id='Ext-data-proxy-Proxy-cfg-defaultWriterType'> /**
|
</span> * @cfg {String} defaultWriterType
|
* The default registered writer type. Defaults to 'json'.
|
* @private
|
*/
|
defaultWriterType: 'json',
|
|
<span id='Ext-data-proxy-Proxy-cfg-model'> /**
|
</span> * @cfg {String/Ext.data.Model} model
|
* The name of the Model to tie to this Proxy. Can be either the string name of the Model, or a reference to the
|
* Model constructor. Required.
|
*/
|
|
<span id='Ext-data-proxy-Proxy-cfg-reader'> /**
|
</span> * @cfg {Object/String/Ext.data.reader.Reader} reader
|
* The Ext.data.reader.Reader to use to decode the server's response or data read from client. This can either be a
|
* Reader instance, a config object or just a valid Reader type name (e.g. 'json', 'xml').
|
*/
|
|
<span id='Ext-data-proxy-Proxy-cfg-writer'> /**
|
</span> * @cfg {Object/String/Ext.data.writer.Writer} writer
|
* The Ext.data.writer.Writer to use to encode any request sent to the server or saved to client. This can either be
|
* a Writer instance, a config object or just a valid Writer type name (e.g. 'json', 'xml').
|
*/
|
|
<span id='Ext-data-proxy-Proxy-property-isProxy'> /**
|
</span> * @property {Boolean} isProxy
|
* `true` in this class to identify an object as an instantiated Proxy, or subclass thereof.
|
*/
|
isProxy: true,
|
|
<span id='Ext-data-proxy-Proxy-property-isSynchronous'> /**
|
</span> * @property {Boolean} [isSynchronous=false]
|
* Identifies the proxy as (a)synchronous.
|
*/
|
isSynchronous: false,
|
|
<span id='Ext-data-proxy-Proxy-method-constructor'> /**
|
</span> * Creates the Proxy
|
* @param {Object} config (optional) Config object.
|
*/
|
constructor: function(config) {
|
var me = this;
|
|
config = config || {};
|
me.proxyConfig = config;
|
|
me.mixins.observable.constructor.call(me, config);
|
|
if (me.model !== undefined && !(me.model instanceof Ext.data.Model)) {
|
me.setModel(me.model);
|
} else {
|
if (me.reader) {
|
me.setReader(me.reader);
|
}
|
|
if (me.writer) {
|
me.setWriter(me.writer);
|
}
|
}
|
|
<span id='Ext-data-proxy-Proxy-event-metachange'> /**
|
</span> * @event metachange
|
* Fires when this proxy's reader provides new metadata. Metadata usually consists
|
* of new field definitions, but can include any configuration data required by an
|
* application, and can be processed as needed in the event handler.
|
* This event is currently only fired for JsonReaders. Note that this event is also
|
* propagated by {@link Ext.data.Store}, which is typically where it would be handled.
|
* @param {Ext.data.proxy.Proxy} this
|
* @param {Object} meta The JSON metadata
|
*/
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-setModel'> /**
|
</span> * Sets the model associated with this proxy. This will only usually be called by a Store
|
*
|
* @param {String/Ext.data.Model} model The new model. Can be either the model name string,
|
* or a reference to the model's constructor
|
* @param {Boolean} setOnStore Sets the new model on the associated Store, if one is present
|
*/
|
setModel: function(model, setOnStore) {
|
var me = this;
|
|
me.model = Ext.ModelManager.getModel(model);
|
|
me.setReader(this.reader);
|
me.setWriter(this.writer);
|
|
if (setOnStore && me.store) {
|
me.store.setModel(me.model);
|
}
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-getModel'> /**
|
</span> * Returns the model attached to this Proxy
|
* @return {Ext.data.Model} The model
|
*/
|
getModel: function() {
|
return this.model;
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-setReader'> /**
|
</span> * Sets the Proxy's Reader by string, config object or Reader instance
|
*
|
* @param {String/Object/Ext.data.reader.Reader} reader The new Reader, which can be either a type string,
|
* a configuration object or an Ext.data.reader.Reader instance
|
* @return {Ext.data.reader.Reader} The attached Reader object
|
*/
|
setReader: function(reader) {
|
var me = this,
|
needsCopy = true,
|
current = me.reader;
|
|
if (reader === undefined || typeof reader == 'string') {
|
reader = {
|
type: reader
|
};
|
needsCopy = false;
|
}
|
|
if (reader.isReader) {
|
reader.setModel(me.model);
|
} else {
|
if (needsCopy) {
|
reader = Ext.apply({}, reader);
|
}
|
Ext.applyIf(reader, {
|
proxy: me,
|
model: me.model,
|
type : me.defaultReaderType
|
});
|
|
reader = Ext.createByAlias('reader.' + reader.type, reader);
|
}
|
|
if (reader !== current && reader.onMetaChange) {
|
reader.onMetaChange = Ext.Function.createSequence(reader.onMetaChange, this.onMetaChange, this);
|
}
|
|
me.reader = reader;
|
return me.reader;
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-getReader'> /**
|
</span> * Returns the reader currently attached to this proxy instance
|
* @return {Ext.data.reader.Reader} The Reader instance
|
*/
|
getReader: function() {
|
return this.reader;
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-onMetaChange'> /**
|
</span> * @private
|
* Called each time the reader's onMetaChange is called so that the proxy can fire the metachange event
|
*/
|
onMetaChange: function(meta) {
|
this.fireEvent('metachange', this, meta);
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-setWriter'> /**
|
</span> * Sets the Proxy's Writer by string, config object or Writer instance
|
*
|
* @param {String/Object/Ext.data.writer.Writer} writer The new Writer, which can be either a type string,
|
* a configuration object or an Ext.data.writer.Writer instance
|
* @return {Ext.data.writer.Writer} The attached Writer object
|
*/
|
setWriter: function(writer) {
|
var me = this,
|
needsCopy = true;
|
|
if (writer === undefined || typeof writer == 'string') {
|
writer = {
|
type: writer
|
};
|
needsCopy = false;
|
}
|
|
if (!writer.isWriter) {
|
if (needsCopy) {
|
writer = Ext.apply({}, writer);
|
}
|
Ext.applyIf(writer, {
|
model: me.model,
|
type : me.defaultWriterType
|
});
|
|
writer = Ext.createByAlias('writer.' + writer.type, writer);
|
}
|
|
me.writer = writer;
|
|
return me.writer;
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-getWriter'> /**
|
</span> * Returns the writer currently attached to this proxy instance
|
* @return {Ext.data.writer.Writer} The Writer instance
|
*/
|
getWriter: function() {
|
return this.writer;
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-create'> /**
|
</span> * Performs the given create operation.
|
* @param {Ext.data.Operation} operation The Operation to perform
|
* @param {Function} callback Callback function to be called when the Operation has completed (whether
|
* successful or not)
|
* @param {Object} scope Scope to execute the callback function in
|
* @method
|
*/
|
create: Ext.emptyFn,
|
|
<span id='Ext-data-proxy-Proxy-method-read'> /**
|
</span> * Performs the given read operation.
|
* @param {Ext.data.Operation} operation The Operation to perform
|
* @param {Function} callback Callback function to be called when the Operation has completed (whether
|
* successful or not)
|
* @param {Object} scope Scope to execute the callback function in
|
* @method
|
*/
|
read: Ext.emptyFn,
|
|
<span id='Ext-data-proxy-Proxy-method-update'> /**
|
</span> * Performs the given update operation.
|
* @param {Ext.data.Operation} operation The Operation to perform
|
* @param {Function} callback Callback function to be called when the Operation has completed (whether
|
* successful or not)
|
* @param {Object} scope Scope to execute the callback function in
|
* @method
|
*/
|
update: Ext.emptyFn,
|
|
<span id='Ext-data-proxy-Proxy-method-destroy'> /**
|
</span> * Performs the given destroy operation.
|
* @param {Ext.data.Operation} operation The Operation to perform
|
* @param {Function} callback Callback function to be called when the Operation has completed (whether
|
* successful or not)
|
* @param {Object} scope Scope to execute the callback function in
|
* @method
|
*/
|
destroy: Ext.emptyFn,
|
|
<span id='Ext-data-proxy-Proxy-method-batch'> /**
|
</span> * Performs a batch of {@link Ext.data.Operation Operations}, in the order specified by {@link #batchOrder}. Used
|
* internally by {@link Ext.data.Store}'s {@link Ext.data.Store#sync sync} method. Example usage:
|
*
|
* myProxy.batch({
|
* create : [myModel1, myModel2],
|
* update : [myModel3],
|
* destroy: [myModel4, myModel5]
|
* });
|
*
|
* Where the myModel* above are {@link Ext.data.Model Model} instances - in this case 1 and 2 are new instances and
|
* have not been saved before, 3 has been saved previously but needs to be updated, and 4 and 5 have already been
|
* saved but should now be destroyed.
|
*
|
* Note that the previous version of this method took 2 arguments (operations and listeners). While this is still
|
* supported for now, the current signature is now a single `options` argument that can contain both operations and
|
* listeners, in addition to other options. The multi-argument signature will likely be deprecated in a future release.
|
*
|
* @param {Object} options Object containing one or more properties supported by the batch method:
|
*
|
* @param {Object} options.operations Object containing the Model instances to act upon, keyed by action name
|
*
|
* @param {Object} [options.listeners] Event listeners object passed straight through to the Batch -
|
* see {@link Ext.data.Batch} for details
|
*
|
* @param {Ext.data.Batch/Object} [options.batch] A {@link Ext.data.Batch} object (or batch config to apply
|
* to the created batch). If unspecified a default batch will be auto-created.
|
*
|
* @param {Function} [options.callback] The function to be called upon completion of processing the batch.
|
* The callback is called regardless of success or failure and is passed the following parameters:
|
* @param {Ext.data.Batch} options.callback.batch The {@link Ext.data.Batch batch} that was processed,
|
* containing all operations in their current state after processing
|
* @param {Object} options.callback.options The options argument that was originally passed into batch
|
*
|
* @param {Function} [options.success] The function to be called upon successful completion of the batch. The
|
* success function is called only if no exceptions were reported in any operations. If one or more exceptions
|
* occurred then the `failure` function will be called instead. The success function is called
|
* with the following parameters:
|
* @param {Ext.data.Batch} options.success.batch The {@link Ext.data.Batch batch} that was processed,
|
* containing all operations in their current state after processing
|
* @param {Object} options.success.options The options argument that was originally passed into batch
|
*
|
* @param {Function} [options.failure] The function to be called upon unsuccessful completion of the batch. The
|
* failure function is called when one or more operations returns an exception during processing (even if some
|
* operations were also successful). In this case you can check the batch's {@link Ext.data.Batch#exceptions
|
* exceptions} array to see exactly which operations had exceptions. The failure function is called with the
|
* following parameters:
|
* @param {Ext.data.Batch} options.failure.batch The {@link Ext.data.Batch batch} that was processed,
|
* containing all operations in their current state after processing
|
* @param {Object} options.failure.options The options argument that was originally passed into batch
|
*
|
* @param {Object} [options.scope] The scope in which to execute any callbacks (i.e. the `this` object inside
|
* the callback, success and/or failure functions). Defaults to the proxy.
|
*
|
* @return {Ext.data.Batch} The newly created Batch
|
*/
|
batch: function(options, /* deprecated */listeners) {
|
var me = this,
|
useBatch = me.batchActions,
|
batch,
|
records,
|
actions, aLen, action, a, r, rLen, record;
|
|
if (options.operations === undefined) {
|
// the old-style (operations, listeners) signature was called
|
// so convert to the single options argument syntax
|
options = {
|
operations: options,
|
listeners: listeners
|
};
|
}
|
|
if (options.batch) {
|
if (Ext.isDefined(options.batch.runOperation)) {
|
batch = Ext.applyIf(options.batch, {
|
proxy: me,
|
listeners: {}
|
});
|
}
|
} else {
|
options.batch = {
|
proxy: me,
|
listeners: options.listeners || {}
|
};
|
}
|
|
if (!batch) {
|
batch = new Ext.data.Batch(options.batch);
|
}
|
|
batch.on('complete', Ext.bind(me.onBatchComplete, me, [options], 0));
|
|
actions = me.batchOrder.split(',');
|
aLen = actions.length;
|
|
for (a = 0; a < aLen; a++) {
|
action = actions[a];
|
records = options.operations[action];
|
|
if (records) {
|
if (useBatch) {
|
batch.add(new Ext.data.Operation({
|
action : action,
|
records : records
|
}));
|
} else {
|
rLen = records.length;
|
|
for (r = 0; r < rLen; r++) {
|
record = records[r];
|
|
batch.add(new Ext.data.Operation({
|
action : action,
|
records : [record]
|
}));
|
}
|
}
|
}
|
}
|
|
batch.start();
|
return batch;
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-onBatchComplete'> /**
|
</span> * @private
|
* The internal callback that the proxy uses to call any specified user callbacks after completion of a batch
|
*/
|
onBatchComplete: function(batchOptions, batch) {
|
var scope = batchOptions.scope || this;
|
|
if (batch.hasException) {
|
if (Ext.isFunction(batchOptions.failure)) {
|
Ext.callback(batchOptions.failure, scope, [batch, batchOptions]);
|
}
|
} else if (Ext.isFunction(batchOptions.success)) {
|
Ext.callback(batchOptions.success, scope, [batch, batchOptions]);
|
}
|
|
if (Ext.isFunction(batchOptions.callback)) {
|
Ext.callback(batchOptions.callback, scope, [batch, batchOptions]);
|
}
|
},
|
|
<span id='Ext-data-proxy-Proxy-method-clone'> clone: function() {
|
</span> return new this.self(this.proxyConfig);
|
}
|
});
|
</pre>
|
</body>
|
</html>
|