X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/docs/source/Reader.html diff --git a/docs/source/Reader.html b/docs/source/Reader.html index 570200a2..1923fab6 100644 --- a/docs/source/Reader.html +++ b/docs/source/Reader.html @@ -1,200 +1,232 @@ -
+ +/** - * @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' - } + + + + +\ No newline at end of file +});The source code + + + + + + +/** + * @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'], - /** - * @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 + /** + * @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 */ - /** - * @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>. + /** + * @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', - /** - * @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. + /** + * @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', - /** - * @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. + /** + * @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: '', - /** - * @cfg {String} messageProperty The name of the property which contains a response message. - * This property is optional. + /** + * @cfg {String} messageProperty + * The name of the property which contains a response message. This property is optional. */ - /** - * @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. + /** + * @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, + /** + * Creates new Reader. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { var me = this; @@ -206,7 +238,7 @@ Ext.define('Ext.data.reader.Reader', { } }, - /** + /** * Sets a new model for the reader. * @private * @param {Object} model The model to set. @@ -223,7 +255,7 @@ Ext.define('Ext.data.reader.Reader', { } }, - /** + /** * 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 @@ -243,11 +275,11 @@ Ext.define('Ext.data.reader.Reader', { } }, - /** - * 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 + /** + * 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) { @@ -263,10 +295,9 @@ Ext.define('Ext.data.reader.Reader', { me.buildExtractors(true); } - /** - * The raw data object that was last passed to readRecords. Stored for further processing if needed - * @property rawData - * @type Mixed + /** + * @property {Object} rawData + * The raw data object that was last passed to readRecords. Stored for further processing if needed */ me.rawData = data; @@ -318,9 +349,9 @@ Ext.define('Ext.data.reader.Reader', { }); }, - /** + /** * 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) { @@ -344,8 +375,7 @@ Ext.define('Ext.data.reader.Reader', { id = me.getId(node); - record = new Model(values, id); - record.raw = node; + record = new Model(values, id, node); records.push(record); if (me.implicitIncludes) { @@ -356,12 +386,12 @@ Ext.define('Ext.data.reader.Reader', { return records; }, - /** + /** * @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) { @@ -392,14 +422,14 @@ Ext.define('Ext.data.reader.Reader', { } }, - /** + /** * @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]; @@ -409,7 +439,7 @@ Ext.define('Ext.data.reader.Reader', { return this.model.prototype.fields.items; }, - /** + /** * @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. @@ -433,7 +463,7 @@ Ext.define('Ext.data.reader.Reader', { return output; }, - /** + /** * @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. @@ -444,20 +474,21 @@ Ext.define('Ext.data.reader.Reader', { return data; }, - /** + /** * @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; }, - /** - * 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 + /** + * 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 */ @@ -467,7 +498,7 @@ Ext.define('Ext.data.reader.Reader', { //</debug> }, - /** + /** * @private * Reconfigures the meta data tied to this Reader */ @@ -488,7 +519,7 @@ Ext.define('Ext.data.reader.Reader', { } }, - /** + /** * Get the idProperty to use for extracting data * @private * @return {String} The id property @@ -501,11 +532,11 @@ Ext.define('Ext.data.reader.Reader', { return prop; }, - /** + /** * @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, @@ -551,7 +582,7 @@ Ext.define('Ext.data.reader.Reader', { me.buildFieldExtractors(); }, - /** + /** * @private */ buildFieldExtractors: function() { @@ -583,4 +614,6 @@ Ext.define('Ext.data.reader.Reader', { success: true }) }); -});