X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/docs/source/Reader.html diff --git a/docs/source/Reader.html b/docs/source/Reader.html index 5ebd2636..1923fab6 100644 --- a/docs/source/Reader.html +++ b/docs/source/Reader.html @@ -3,8 +3,8 @@
/** * @author Ed Spencer - * @class Ext.data.reader.Reader - * @extends Object + * + * 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: * - * <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' - } - } -}); - -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> - * -<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: - * -<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> + * 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" } + * ] + * } * + * + * # 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, @@ -263,10 +276,10 @@ 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) { @@ -283,9 +296,8 @@ Ext.define('Ext.data.reader.Reader', { } /** - * 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; @@ -339,7 +351,7 @@ 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) { @@ -379,7 +391,7 @@ Ext.define('Ext.data.reader.Reader', { * 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) { @@ -415,9 +427,9 @@ Ext.define('Ext.data.reader.Reader', { * 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]; @@ -467,15 +479,16 @@ Ext.define('Ext.data.reader.Reader', { * 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 */ @@ -523,7 +536,7 @@ Ext.define('Ext.data.reader.Reader', { * @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,