-<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-data.reader.Reader-method-constructor'><span id='Ext-data.reader.Reader'>/**
-</span></span> * @author Ed Spencer
- * @class Ext.data.reader.Reader
- * @extends Object
- *
- * <p>Readers are used to interpret data to be loaded into a {@link Ext.data.Model Model} instance or a {@link Ext.data.Store Store}
- * - usually in response to an AJAX request. This is normally handled transparently by passing some configuration to either the
- * {@link Ext.data.Model Model} or the {@link Ext.data.Store Store} in question - see their documentation for further details.</p>
- *
- * <p><u>Loading Nested Data</u></p>
- *
- * <p>Readers have the ability to automatically load deeply-nested data objects based on the {@link Ext.data.Association associations}
- * configured on each Model. Below is an example demonstrating the flexibility of these associations in a fictional CRM system which
- * manages a User, their Orders, OrderItems and Products. First we'll define the models:
- *
-<pre><code>
-Ext.define("User", {
- extend: 'Ext.data.Model',
- fields: [
- 'id', 'name'
- ],
-
- hasMany: {model: 'Order', name: 'orders'},
-
- proxy: {
- type: 'rest',
- url : 'users.json',
- reader: {
- type: 'json',
- root: 'users'
- }
+<!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";
}
-});
-
-Ext.define("Order", {
- extend: 'Ext.data.Model',
- fields: [
- 'id', 'total'
- ],
-
- hasMany : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
- belongsTo: 'User'
-});
-
-Ext.define("OrderItem", {
- extend: 'Ext.data.Model',
- fields: [
- 'id', 'price', 'quantity', 'order_id', 'product_id'
- ],
-
- belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
-});
-
-Ext.define("Product", {
- extend: 'Ext.data.Model',
- fields: [
- 'id', 'name'
- ],
-
- hasMany: 'OrderItem'
-});
-</code></pre>
- *
- * <p>This may be a lot to take in - basically a User has many Orders, each of which is composed of several OrderItems. Finally,
- * each OrderItem has a single Product. This allows us to consume data like this:</p>
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='Ext-data-reader-Reader'>/**
+</span> * @author Ed Spencer
+ *
+ * Readers are used to interpret data to be loaded into a {@link Ext.data.Model Model} instance or a {@link
+ * Ext.data.Store Store} - often in response to an AJAX request. In general there is usually no need to create
+ * a Reader instance directly, since a Reader is almost always used together with a {@link Ext.data.proxy.Proxy Proxy},
+ * and is configured using the Proxy's {@link Ext.data.proxy.Proxy#cfg-reader reader} configuration property:
*
-<pre><code>
-{
- "users": [
- {
- "id": 123,
- "name": "Ed",
- "orders": [
- {
- "id": 50,
- "total": 100,
- "order_items": [
- {
- "id" : 20,
- "price" : 40,
- "quantity": 2,
- "product" : {
- "id": 1000,
- "name": "MacBook Pro"
- }
- },
- {
- "id" : 21,
- "price" : 20,
- "quantity": 3,
- "product" : {
- "id": 1001,
- "name": "iPhone"
- }
- }
- ]
- }
- ]
- }
- ]
-}
-</code></pre>
- *
- * <p>The JSON response is deeply nested - it returns all Users (in this case just 1 for simplicity's sake), all of the Orders
- * for each User (again just 1 in this case), all of the OrderItems for each Order (2 order items in this case), and finally
- * the Product associated with each OrderItem. Now we can read the data and use it as follows:
+ * Ext.create('Ext.data.Store', {
+ * model: 'User',
+ * proxy: {
+ * type: 'ajax',
+ * url : 'users.json',
+ * reader: {
+ * type: 'json',
+ * root: 'users'
+ * }
+ * },
+ * });
+ *
+ * The above reader is configured to consume a JSON string that looks something like this:
+ *
+ * {
+ * "success": true,
+ * "users": [
+ * { "name": "User 1" },
+ * { "name": "User 2" }
+ * ]
+ * }
*
-<pre><code>
-var store = new Ext.data.Store({
- model: "User"
-});
-
-store.load({
- callback: function() {
- //the user that was loaded
- var user = store.first();
-
- console.log("Orders for " + user.get('name') + ":")
-
- //iterate over the Orders for each User
- user.orders().each(function(order) {
- console.log("Order ID: " + order.getId() + ", which contains items:");
-
- //iterate over the OrderItems for each Order
- order.orderItems().each(function(orderItem) {
- //we know that the Product data is already loaded, so we can use the synchronous getProduct
- //usually, we would use the asynchronous version (see {@link Ext.data.BelongsToAssociation})
- var product = orderItem.getProduct();
-
- console.log(orderItem.get('quantity') + ' orders of ' + product.get('name'));
- });
- });
- }
-});
-</code></pre>
- *
- * <p>Running the code above results in the following:</p>
- *
-<pre><code>
-Orders for Ed:
-Order ID: 50, which contains items:
-2 orders of MacBook Pro
-3 orders of iPhone
-</code></pre>
- *
- * @constructor
- * @param {Object} config Optional config object
+ *
+ * # Loading Nested Data
+ *
+ * Readers have the ability to automatically load deeply-nested data objects based on the {@link Ext.data.Association
+ * associations} configured on each Model. Below is an example demonstrating the flexibility of these associations in a
+ * fictional CRM system which manages a User, their Orders, OrderItems and Products. First we'll define the models:
+ *
+ * Ext.define("User", {
+ * extend: 'Ext.data.Model',
+ * fields: [
+ * 'id', 'name'
+ * ],
+ *
+ * hasMany: {model: 'Order', name: 'orders'},
+ *
+ * proxy: {
+ * type: 'rest',
+ * url : 'users.json',
+ * reader: {
+ * type: 'json',
+ * root: 'users'
+ * }
+ * }
+ * });
+ *
+ * Ext.define("Order", {
+ * extend: 'Ext.data.Model',
+ * fields: [
+ * 'id', 'total'
+ * ],
+ *
+ * hasMany : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
+ * belongsTo: 'User'
+ * });
+ *
+ * Ext.define("OrderItem", {
+ * extend: 'Ext.data.Model',
+ * fields: [
+ * 'id', 'price', 'quantity', 'order_id', 'product_id'
+ * ],
+ *
+ * belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
+ * });
+ *
+ * Ext.define("Product", {
+ * extend: 'Ext.data.Model',
+ * fields: [
+ * 'id', 'name'
+ * ],
+ *
+ * hasMany: 'OrderItem'
+ * });
+ *
+ * This may be a lot to take in - basically a User has many Orders, each of which is composed of several OrderItems.
+ * Finally, each OrderItem has a single Product. This allows us to consume data like this:
+ *
+ * {
+ * "users": [
+ * {
+ * "id": 123,
+ * "name": "Ed",
+ * "orders": [
+ * {
+ * "id": 50,
+ * "total": 100,
+ * "order_items": [
+ * {
+ * "id" : 20,
+ * "price" : 40,
+ * "quantity": 2,
+ * "product" : {
+ * "id": 1000,
+ * "name": "MacBook Pro"
+ * }
+ * },
+ * {
+ * "id" : 21,
+ * "price" : 20,
+ * "quantity": 3,
+ * "product" : {
+ * "id": 1001,
+ * "name": "iPhone"
+ * }
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ *
+ * The JSON response is deeply nested - it returns all Users (in this case just 1 for simplicity's sake), all of the
+ * Orders for each User (again just 1 in this case), all of the OrderItems for each Order (2 order items in this case),
+ * and finally the Product associated with each OrderItem. Now we can read the data and use it as follows:
+ *
+ * var store = Ext.create('Ext.data.Store', {
+ * model: "User"
+ * });
+ *
+ * store.load({
+ * callback: function() {
+ * //the user that was loaded
+ * var user = store.first();
+ *
+ * console.log("Orders for " + user.get('name') + ":")
+ *
+ * //iterate over the Orders for each User
+ * user.orders().each(function(order) {
+ * console.log("Order ID: " + order.getId() + ", which contains items:");
+ *
+ * //iterate over the OrderItems for each Order
+ * order.orderItems().each(function(orderItem) {
+ * //we know that the Product data is already loaded, so we can use the synchronous getProduct
+ * //usually, we would use the asynchronous version (see {@link Ext.data.BelongsToAssociation})
+ * var product = orderItem.getProduct();
+ *
+ * console.log(orderItem.get('quantity') + ' orders of ' + product.get('name'));
+ * });
+ * });
+ * }
+ * });
+ *
+ * Running the code above results in the following:
+ *
+ * Orders for Ed:
+ * Order ID: 50, which contains items:
+ * 2 orders of MacBook Pro
+ * 3 orders of iPhone
*/
Ext.define('Ext.data.reader.Reader', {
requires: ['Ext.data.ResultSet'],
alternateClassName: ['Ext.data.Reader', 'Ext.data.DataReader'],
-<span id='Ext-data.reader.Reader-cfg-idProperty'> /**
-</span> * @cfg {String} idProperty Name of the property within a row object
- * that contains a record identifier value. Defaults to <tt>The id of the model</tt>.
- * If an idProperty is explicitly specified it will override that of the one specified
- * on the model
+<span id='Ext-data-reader-Reader-cfg-idProperty'> /**
+</span> * @cfg {String} idProperty
+ * Name of the property within a row object that contains a record identifier value. Defaults to The id of the
+ * model. If an idProperty is explicitly specified it will override that of the one specified on the model
*/
-<span id='Ext-data.reader.Reader-cfg-totalProperty'> /**
-</span> * @cfg {String} totalProperty Name of the property from which to
- * retrieve the total number of records in the dataset. This is only needed
- * if the whole dataset is not passed in one go, but is being paged from
- * the remote server. Defaults to <tt>total</tt>.
+<span id='Ext-data-reader-Reader-cfg-totalProperty'> /**
+</span> * @cfg {String} totalProperty
+ * Name of the property from which to retrieve the total number of records in the dataset. This is only needed if
+ * the whole dataset is not passed in one go, but is being paged from the remote server. Defaults to total.
*/
totalProperty: 'total',
-<span id='Ext-data.reader.Reader-cfg-successProperty'> /**
-</span> * @cfg {String} successProperty Name of the property from which to
- * retrieve the success attribute. Defaults to <tt>success</tt>. See
- * {@link Ext.data.proxy.Proxy}.{@link Ext.data.proxy.Proxy#exception exception}
- * for additional information.
+<span id='Ext-data-reader-Reader-cfg-successProperty'> /**
+</span> * @cfg {String} successProperty
+ * Name of the property from which to retrieve the success attribute. Defaults to success. See
+ * {@link Ext.data.proxy.Server}.{@link Ext.data.proxy.Server#exception exception} for additional information.
*/
successProperty: 'success',
-<span id='Ext-data.reader.Reader-cfg-root'> /**
-</span> * @cfg {String} root <b>Required</b>. The name of the property
- * which contains the Array of row objects. Defaults to <tt>undefined</tt>.
- * An exception will be thrown if the root property is undefined. The data
- * packet value for this property should be an empty array to clear the data
- * or show no data.
+<span id='Ext-data-reader-Reader-cfg-root'> /**
+</span> * @cfg {String} root
+ * The name of the property which contains the Array of row objects. For JSON reader it's dot-separated list
+ * of property names. For XML reader it's a CSS selector. For array reader it's not applicable.
+ *
+ * By default the natural root of the data will be used. The root Json array, the root XML element, or the array.
+ *
+ * The data packet value for this property should be an empty array to clear the data or show no data.
*/
root: '',
-<span id='Ext-data.reader.Reader-cfg-messageProperty'> /**
-</span> * @cfg {String} messageProperty The name of the property which contains a response message.
- * This property is optional.
+<span id='Ext-data-reader-Reader-cfg-messageProperty'> /**
+</span> * @cfg {String} messageProperty
+ * The name of the property which contains a response message. This property is optional.
*/
-<span id='Ext-data.reader.Reader-cfg-implicitIncludes'> /**
-</span> * @cfg {Boolean} implicitIncludes True to automatically parse models nested within other models in a response
- * object. See the Ext.data.reader.Reader intro docs for full explanation. Defaults to true.
+<span id='Ext-data-reader-Reader-cfg-implicitIncludes'> /**
+</span> * @cfg {Boolean} implicitIncludes
+ * True to automatically parse models nested within other models in a response object. See the
+ * Ext.data.reader.Reader intro docs for full explanation. Defaults to true.
*/
implicitIncludes: true,
isReader: true,
+<span id='Ext-data-reader-Reader-method-constructor'> /**
+</span> * Creates new Reader.
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(config) {
var me = this;
}
},
-<span id='Ext-data.reader.Reader-method-setModel'> /**
+<span id='Ext-data-reader-Reader-method-setModel'> /**
</span> * Sets a new model for the reader.
* @private
* @param {Object} model The model to set.
}
},
-<span id='Ext-data.reader.Reader-method-read'> /**
+<span id='Ext-data-reader-Reader-method-read'> /**
</span> * Reads the given response object. This method normalizes the different types of response object that may be passed
* to it, before handing off the reading of records to the {@link #readRecords} function.
* @param {Object} response The response object. This may be either an XMLHttpRequest object or a plain JS object
}
},
-<span id='Ext-data.reader.Reader-method-readRecords'> /**
-</span> * Abstracts common functionality used by all Reader subclasses. Each subclass is expected to call
- * this function before running its own logic and returning the Ext.data.ResultSet instance. For most
- * Readers additional processing should not be needed.
- * @param {Mixed} data The raw data object
+<span id='Ext-data-reader-Reader-method-readRecords'> /**
+</span> * Abstracts common functionality used by all Reader subclasses. Each subclass is expected to call this function
+ * before running its own logic and returning the Ext.data.ResultSet instance. For most Readers additional
+ * processing should not be needed.
+ * @param {Object} data The raw data object
* @return {Ext.data.ResultSet} A ResultSet object
*/
readRecords: function(data) {
me.buildExtractors(true);
}
-<span id='Ext-data.reader.Reader-property-rawData'> /**
-</span> * The raw data object that was last passed to readRecords. Stored for further processing if needed
- * @property rawData
- * @type Mixed
+<span id='Ext-data-reader-Reader-property-rawData'> /**
+</span> * @property {Object} rawData
+ * The raw data object that was last passed to readRecords. Stored for further processing if needed
*/
me.rawData = data;
});
},
-<span id='Ext-data.reader.Reader-method-extractData'> /**
+<span id='Ext-data-reader-Reader-method-extractData'> /**
</span> * Returns extracted, type-cast rows of data. Iterates to call #extractValues for each row
- * @param {Object[]/Object} data-root from server response
+ * @param {Object[]/Object} root from server response
* @private
*/
extractData : function(root) {
id = me.getId(node);
- record = new Model(values, id);
- record.raw = node;
+ record = new Model(values, id, node);
records.push(record);
if (me.implicitIncludes) {
return records;
},
-<span id='Ext-data.reader.Reader-method-readAssociated'> /**
+<span id='Ext-data-reader-Reader-method-readAssociated'> /**
</span> * @private
* Loads a record's associations from the data object. This prepopulates hasMany and belongsTo associations
* on the record provided.
* @param {Ext.data.Model} record The record to load associations for
- * @param {Mixed} data The data object
+ * @param {Object} data The data object
* @return {String} Return value description
*/
readAssociated: function(record, data) {
}
},
-<span id='Ext-data.reader.Reader-method-getAssociatedDataRoot'> /**
+<span id='Ext-data-reader-Reader-method-getAssociatedDataRoot'> /**
</span> * @private
* Used internally by {@link #readAssociated}. Given a data object (which could be json, xml etc) for a specific
* record, this should return the relevant part of that data for the given association name. This is only really
* needed to support the XML Reader, which has to do a query to get the associated data object
- * @param {Mixed} data The raw data object
+ * @param {Object} data The raw data object
* @param {String} associationName The name of the association to get data for (uses associationKey if present)
- * @return {Mixed} The root
+ * @return {Object} The root
*/
getAssociatedDataRoot: function(data, associationName) {
return data[associationName];
return this.model.prototype.fields.items;
},
-<span id='Ext-data.reader.Reader-method-extractValues'> /**
+<span id='Ext-data-reader-Reader-method-extractValues'> /**
</span> * @private
* Given an object representing a single model instance's data, iterates over the model's fields and
* builds an object with the value for each field.
return output;
},
-<span id='Ext-data.reader.Reader-method-getData'> /**
+<span id='Ext-data-reader-Reader-method-getData'> /**
</span> * @private
* By default this function just returns what is passed to it. It can be overridden in a subclass
* to return something else. See XmlReader for an example.
return data;
},
-<span id='Ext-data.reader.Reader-method-getRoot'> /**
+<span id='Ext-data-reader-Reader-method-getRoot'> /**
</span> * @private
* This will usually need to be implemented in a subclass. Given a generic data object (the type depends on the type
* of data we are reading), this function should return the object as configured by the Reader's 'root' meta data config.
* See XmlReader's getRoot implementation for an example. By default the same data object will simply be returned.
- * @param {Mixed} data The data object
- * @return {Mixed} The same data object
+ * @param {Object} data The data object
+ * @return {Object} The same data object
*/
getRoot: function(data) {
return data;
},
-<span id='Ext-data.reader.Reader-method-getResponseData'> /**
-</span> * Takes a raw response object (as passed to this.read) and returns the useful data segment of it. This must be implemented by each subclass
+<span id='Ext-data-reader-Reader-method-getResponseData'> /**
+</span> * Takes a raw response object (as passed to this.read) and returns the useful data segment of it. This must be
+ * implemented by each subclass
* @param {Object} response The responce object
* @return {Object} The useful data from the response
*/
//</debug>
},
-<span id='Ext-data.reader.Reader-method-onMetaChange'> /**
+<span id='Ext-data-reader-Reader-method-onMetaChange'> /**
</span> * @private
* Reconfigures the meta data tied to this Reader
*/
}
},
-<span id='Ext-data.reader.Reader-method-getIdProperty'> /**
+<span id='Ext-data-reader-Reader-method-getIdProperty'> /**
</span> * Get the idProperty to use for extracting data
* @private
* @return {String} The id property
return prop;
},
-<span id='Ext-data.reader.Reader-method-buildExtractors'> /**
+<span id='Ext-data-reader-Reader-method-buildExtractors'> /**
</span> * @private
* This builds optimized functions for retrieving record data and meta data from an object.
* Subclasses may need to implement their own getRoot function.
- * @param {Boolean} force True to automatically remove existing extractor functions first (defaults to false)
+ * @param {Boolean} [force=false] True to automatically remove existing extractor functions first
*/
buildExtractors: function(force) {
var me = this,
me.buildFieldExtractors();
},
-<span id='Ext-data.reader.Reader-method-buildFieldExtractors'> /**
+<span id='Ext-data-reader-Reader-method-buildFieldExtractors'> /**
</span> * @private
*/
buildFieldExtractors: function() {
success: true
})
});
-});</pre></pre></body></html>
\ No newline at end of file
+});</pre>
+</body>
+</html>