Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Reader.html
index 5ebd263..1923fab 100644 (file)
@@ -3,8 +3,8 @@
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>The source code</title>
-  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
-  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <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>
 <body onload="prettyPrint(); highlight();">
   <pre class="prettyprint lang-js"><span id='Ext-data-reader-Reader'>/**
 </span> * @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:
  * 
- * &lt;p&gt;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.&lt;/p&gt;
- * 
- * &lt;p&gt;&lt;u&gt;Loading Nested Data&lt;/u&gt;&lt;/p&gt;
- * 
- * &lt;p&gt;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:
- * 
-&lt;pre&gt;&lt;code&gt;
-Ext.define(&quot;User&quot;, {
-    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(&quot;Order&quot;, {
-    extend: 'Ext.data.Model',
-    fields: [
-        'id', 'total'
-    ],
-
-    hasMany  : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
-    belongsTo: 'User'
-});
-
-Ext.define(&quot;OrderItem&quot;, {
-    extend: 'Ext.data.Model',
-    fields: [
-        'id', 'price', 'quantity', 'order_id', 'product_id'
-    ],
-
-    belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
-});
-
-Ext.define(&quot;Product&quot;, {
-    extend: 'Ext.data.Model',
-    fields: [
-        'id', 'name'
-    ],
-
-    hasMany: 'OrderItem'
-});
-&lt;/code&gt;&lt;/pre&gt;
- * 
- * &lt;p&gt;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:&lt;/p&gt;
- * 
-&lt;pre&gt;&lt;code&gt;
-{
-    &quot;users&quot;: [
-        {
-            &quot;id&quot;: 123,
-            &quot;name&quot;: &quot;Ed&quot;,
-            &quot;orders&quot;: [
-                {
-                    &quot;id&quot;: 50,
-                    &quot;total&quot;: 100,
-                    &quot;order_items&quot;: [
-                        {
-                            &quot;id&quot;      : 20,
-                            &quot;price&quot;   : 40,
-                            &quot;quantity&quot;: 2,
-                            &quot;product&quot; : {
-                                &quot;id&quot;: 1000,
-                                &quot;name&quot;: &quot;MacBook Pro&quot;
-                            }
-                        },
-                        {
-                            &quot;id&quot;      : 21,
-                            &quot;price&quot;   : 20,
-                            &quot;quantity&quot;: 3,
-                            &quot;product&quot; : {
-                                &quot;id&quot;: 1001,
-                                &quot;name&quot;: &quot;iPhone&quot;
-                            }
-                        }
-                    ]
-                }
-            ]
-        }
-    ]
-}
-&lt;/code&gt;&lt;/pre&gt;
- * 
- * &lt;p&gt;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:
- * 
-&lt;pre&gt;&lt;code&gt;
-var store = new Ext.data.Store({
-    model: &quot;User&quot;
-});
-
-store.load({
-    callback: function() {
-        //the user that was loaded
-        var user = store.first();
-
-        console.log(&quot;Orders for &quot; + user.get('name') + &quot;:&quot;)
-
-        //iterate over the Orders for each User
-        user.orders().each(function(order) {
-            console.log(&quot;Order ID: &quot; + order.getId() + &quot;, which contains items:&quot;);
-
-            //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'));
-            });
-        });
-    }
-});
-&lt;/code&gt;&lt;/pre&gt;
- * 
- * &lt;p&gt;Running the code above results in the following:&lt;/p&gt;
- * 
-&lt;pre&gt;&lt;code&gt;
-Orders for Ed:
-Order ID: 50, which contains items:
-2 orders of MacBook Pro
-3 orders of iPhone
-&lt;/code&gt;&lt;/pre&gt;
+ *     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:
+ *  
+ *     {
+ *         &quot;success&quot;: true,
+ *         &quot;users&quot;: [
+ *             { &quot;name&quot;: &quot;User 1&quot; },
+ *             { &quot;name&quot;: &quot;User 2&quot; }
+ *         ]
+ *     }
  * 
+ *
+ * # 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(&quot;User&quot;, {
+ *         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(&quot;Order&quot;, {
+ *         extend: 'Ext.data.Model',
+ *         fields: [
+ *             'id', 'total'
+ *         ],
+ *
+ *         hasMany  : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
+ *         belongsTo: 'User'
+ *     });
+ *
+ *     Ext.define(&quot;OrderItem&quot;, {
+ *         extend: 'Ext.data.Model',
+ *         fields: [
+ *             'id', 'price', 'quantity', 'order_id', 'product_id'
+ *         ],
+ *
+ *         belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
+ *     });
+ *
+ *     Ext.define(&quot;Product&quot;, {
+ *         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:
+ *
+ *     {
+ *         &quot;users&quot;: [
+ *             {
+ *                 &quot;id&quot;: 123,
+ *                 &quot;name&quot;: &quot;Ed&quot;,
+ *                 &quot;orders&quot;: [
+ *                     {
+ *                         &quot;id&quot;: 50,
+ *                         &quot;total&quot;: 100,
+ *                         &quot;order_items&quot;: [
+ *                             {
+ *                                 &quot;id&quot;      : 20,
+ *                                 &quot;price&quot;   : 40,
+ *                                 &quot;quantity&quot;: 2,
+ *                                 &quot;product&quot; : {
+ *                                     &quot;id&quot;: 1000,
+ *                                     &quot;name&quot;: &quot;MacBook Pro&quot;
+ *                                 }
+ *                             },
+ *                             {
+ *                                 &quot;id&quot;      : 21,
+ *                                 &quot;price&quot;   : 20,
+ *                                 &quot;quantity&quot;: 3,
+ *                                 &quot;product&quot; : {
+ *                                     &quot;id&quot;: 1001,
+ *                                     &quot;name&quot;: &quot;iPhone&quot;
+ *                                 }
+ *                             }
+ *                         ]
+ *                     }
+ *                 ]
+ *             }
+ *         ]
+ *     }
+ *
+ * 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: &quot;User&quot;
+ *     });
+ *
+ *     store.load({
+ *         callback: function() {
+ *             //the user that was loaded
+ *             var user = store.first();
+ *
+ *             console.log(&quot;Orders for &quot; + user.get('name') + &quot;:&quot;)
+ *
+ *             //iterate over the Orders for each User
+ *             user.orders().each(function(order) {
+ *                 console.log(&quot;Order ID: &quot; + order.getId() + &quot;, which contains items:&quot;);
+ *
+ *                 //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 &lt;tt&gt;The id of the model&lt;/tt&gt;.
-     * If an idProperty is explicitly specified it will override that of the one specified
-     * on the model
+</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 &lt;tt&gt;total&lt;/tt&gt;.
+</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 &lt;tt&gt;success&lt;/tt&gt;.  See
-     * {@link Ext.data.proxy.Proxy}.{@link Ext.data.proxy.Proxy#exception exception}
-     * for additional information.
+</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 &lt;b&gt;Required&lt;/b&gt;.  The name of the property
-     * which contains the Array of row objects.  Defaults to &lt;tt&gt;undefined&lt;/tt&gt;.
-     * 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>     * @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>     * @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>     * @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', {
     },
 
 <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>     * 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', {
         }
         
 <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>         * @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', {
 
 <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) {
@@ -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;
     },
 
 <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>     * 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', {
 </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,