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 @@ -Sencha Documentation Project
/**
- * @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'
-        }
+
+
+
+  
+  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
         })
     });
-});
\ No newline at end of file +});
+ +