Upgrade to ExtJS 3.0.3 - Released 10/11/2009
[extjs.git] / docs / source / Store.html
index 4937025..d069820 100644 (file)
@@ -1,11 +1,17 @@
-<html>\r
-<head>\r
-  <title>The source code</title>\r
-    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
-    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
-</head>\r
-<body  onload="prettyPrint();">\r
-    <pre class="prettyprint lang-js"><div id="cls-Ext.data.Store"></div>/**
+<html>
+<head>
+  <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>
+</head>
+<body  onload="prettyPrint();">
+    <pre class="prettyprint lang-js">/*!
+ * Ext JS Library 3.0.3
+ * Copyright(c) 2006-2009 Ext JS, LLC
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+<div id="cls-Ext.data.Store"></div>/**
  * @class Ext.data.Store
  * @extends Ext.util.Observable
  * <p>The Store class encapsulates a client side cache of {@link Ext.data.Record Record}
  * @class Ext.data.Store
  * @extends Ext.util.Observable
  * <p>The Store class encapsulates a client side cache of {@link Ext.data.Record Record}
@@ -68,6 +74,9 @@ var recId = 100; // provide unique id for the record
 var r = new myStore.recordType(defaultData, ++recId); // create new record
 myStore.{@link #insert}(0, r); // insert a new record into the store (also see {@link #add})
  * </code></pre>
 var r = new myStore.recordType(defaultData, ++recId); // create new record
 myStore.{@link #insert}(0, r); // insert a new record into the store (also see {@link #add})
  * </code></pre>
+ * <p><u>Writing Data</u></p>
+ * <p>And <b>new in Ext version 3</b>, use the new {@link Ext.data.DataWriter DataWriter} to create an automated, <a href="http://extjs.com/deploy/dev/examples/writer/writer.html">Writable Store</a>
+ * along with <a href="http://extjs.com/deploy/dev/examples/restful/restful.html">RESTful features.</a>
  * @constructor
  * Creates a new Store.
  * @param {Object} config A config object containing the objects needed for the Store to access data,
  * @constructor
  * Creates a new Store.
  * @param {Object} config A config object containing the objects needed for the Store to access data,
@@ -96,7 +105,7 @@ Ext.data.Store = function(config){
     }
 
     Ext.apply(this, config);
     }
 
     Ext.apply(this, config);
-    
+
     this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
 
     if(this.url && !this.proxy){
     this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
 
     if(this.url && !this.proxy){
@@ -114,7 +123,8 @@ Ext.data.Store = function(config){
             this.recordType = this.reader.recordType;
         }
         if(this.reader.onMetaChange){
             this.recordType = this.reader.recordType;
         }
         if(this.reader.onMetaChange){
-            this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
+            //this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
+            this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
         }
         if (this.writer) { // writer passed
             this.writer.meta = this.reader.meta;
         }
         if (this.writer) { // writer passed
             this.writer.meta = this.reader.meta;
@@ -246,6 +256,7 @@ var grid = new Ext.grid.EditorGridPanel({
          * @event clear
          * Fires when the data cache has been cleared.
          * @param {Store} this
          * @event clear
          * Fires when the data cache has been cleared.
          * @param {Store} this
+         * @param {Record[]} The records that were cleared.
          */
         'clear',
         <div id="event-Ext.data.Store-exception"></div>/**
          */
         'clear',
         <div id="event-Ext.data.Store-exception"></div>/**
@@ -287,7 +298,7 @@ var grid = new Ext.grid.EditorGridPanel({
         'loadexception',
         <div id="event-Ext.data.Store-beforewrite"></div>/**
          * @event beforewrite
         'loadexception',
         <div id="event-Ext.data.Store-beforewrite"></div>/**
          * @event beforewrite
-         * @param {DataProxy} this
+         * @param {Ext.data.Store} store
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]
          * @param {Record/Array[Record]} rs
          * @param {Object} options The loading options that were specified. Edit <code>options.params</code> to add Http parameters to the request.  (see {@link #save} for details)
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]
          * @param {Record/Array[Record]} rs
          * @param {Object} options The loading options that were specified. Edit <code>options.params</code> to add Http parameters to the request.  (see {@link #save} for details)
@@ -297,9 +308,8 @@ var grid = new Ext.grid.EditorGridPanel({
         <div id="event-Ext.data.Store-write"></div>/**
          * @event write
          * Fires if the server returns 200 after an Ext.data.Api.actions CRUD action.
         <div id="event-Ext.data.Store-write"></div>/**
          * @event write
          * Fires if the server returns 200 after an Ext.data.Api.actions CRUD action.
-         * Success or failure of the action is available in the <code>result['successProperty']</code> property.
-         * The server-code might set the <code>successProperty</code> to <tt>false</tt> if a database validation
-         * failed, for example.
+         * Success of the action is determined in the <code>result['successProperty']</code>property (<b>NOTE</b> for RESTful stores,
+         * a simple 20x response is sufficient for the actions "destroy" and "update".  The "create" action should should return 200 along with a database pk).
          * @param {Ext.data.Store} store
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]
          * @param {Object} result The 'data' picked-out out of the response for convenience.
          * @param {Ext.data.Store} store
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]
          * @param {Object} result The 'data' picked-out out of the response for convenience.
@@ -318,7 +328,8 @@ var grid = new Ext.grid.EditorGridPanel({
             scope: this,
             add: this.createRecords,
             remove: this.destroyRecord,
             scope: this,
             add: this.createRecords,
             remove: this.destroyRecord,
-            update: this.updateRecord
+            update: this.updateRecord,
+            clear: this.onClear
         });
     }
 
         });
     }
 
@@ -496,7 +507,7 @@ sortInfo: {
      * internally be set to <tt>false</tt>.</p>
      */
     restful: false,
      * internally be set to <tt>false</tt>.</p>
      */
     restful: false,
-    
+
     <div id="cfg-Ext.data.Store-paramNames"></div>/**
      * @cfg {Object} paramNames
      * <p>An object containing properties which specify the names of the paging and
     <div id="cfg-Ext.data.Store-paramNames"></div>/**
      * @cfg {Object} paramNames
      * <p>An object containing properties which specify the names of the paging and
@@ -516,7 +527,7 @@ sortInfo: {
      * the parameter names to use in its {@link #load requests}.
      */
     paramNames : undefined,
      * the parameter names to use in its {@link #load requests}.
      */
     paramNames : undefined,
-    
+
     <div id="cfg-Ext.data.Store-defaultParamNames"></div>/**
      * @cfg {Object} defaultParamNames
      * Provides the default values for the {@link #paramNames} property. To globally modify the parameters
     <div id="cfg-Ext.data.Store-defaultParamNames"></div>/**
      * @cfg {Object} defaultParamNames
      * Provides the default values for the {@link #paramNames} property. To globally modify the parameters
@@ -533,13 +544,17 @@ sortInfo: {
      * Destroys the store.
      */
     destroy : function(){
      * Destroys the store.
      */
     destroy : function(){
-        if(this.storeId){
-            Ext.StoreMgr.unregister(this);
+        if(!this.isDestroyed){
+            if(this.storeId){
+                Ext.StoreMgr.unregister(this);
+            }
+            this.clearData();
+            this.data = null;
+            Ext.destroy(this.proxy);
+            this.reader = this.writer = null;
+            this.purgeListeners();
+            this.isDestroyed = true;
         }
         }
-        this.data = null;
-        Ext.destroy(this.proxy);
-        this.reader = this.writer = null;
-        this.purgeListeners();
     },
 
     <div id="method-Ext.data.Store-add"></div>/**
     },
 
     <div id="method-Ext.data.Store-add"></div>/**
@@ -582,6 +597,7 @@ sortInfo: {
     remove : function(record){
         var index = this.data.indexOf(record);
         if(index > -1){
     remove : function(record){
         var index = this.data.indexOf(record);
         if(index > -1){
+            record.join(null);
             this.data.removeAt(index);
             if(this.pruneModifiedRecords){
                 this.modified.remove(record);
             this.data.removeAt(index);
             if(this.pruneModifiedRecords){
                 this.modified.remove(record);
@@ -605,14 +621,25 @@ sortInfo: {
      * Remove all Records from the Store and fires the {@link #clear} event.
      */
     removeAll : function(){
      * Remove all Records from the Store and fires the {@link #clear} event.
      */
     removeAll : function(){
-        this.data.clear();
+        var items = [];
+        this.each(function(rec){
+            items.push(rec);
+        });
+        this.clearData();
         if(this.snapshot){
             this.snapshot.clear();
         }
         if(this.pruneModifiedRecords){
             this.modified = [];
         }
         if(this.snapshot){
             this.snapshot.clear();
         }
         if(this.pruneModifiedRecords){
             this.modified = [];
         }
-        this.fireEvent('clear', this);
+        this.fireEvent('clear', this, items);
+    },
+
+    // private
+    onClear: function(store, records){
+        Ext.each(records, function(rec, index){
+            this.destroyRecord(this, rec, index);
+        }, this);
     },
 
     <div id="method-Ext.data.Store-insert"></div>/**
     },
 
     <div id="method-Ext.data.Store-insert"></div>/**
@@ -684,6 +711,14 @@ sortInfo: {
         this.lastOptions = o;
     },
 
         this.lastOptions = o;
     },
 
+    // private
+    clearData: function(){
+        this.data.each(function(rec) {
+            rec.join(null);
+        });
+        this.data.clear();
+    },
+
     <div id="method-Ext.data.Store-load"></div>/**
      * <p>Loads the Record cache from the configured <tt>{@link #proxy}</tt> using the configured <tt>{@link #reader}</tt>.</p>
      * <br><p>Notes:</p><div class="mdetail-params"><ul>
     <div id="method-Ext.data.Store-load"></div>/**
      * <p>Loads the Record cache from the configured <tt>{@link #proxy}</tt> using the configured <tt>{@link #reader}</tt>.</p>
      * <br><p>Notes:</p><div class="mdetail-params"><ul>
@@ -815,10 +850,12 @@ sortInfo: {
         var doRequest = true;
 
         if (action === 'read') {
         var doRequest = true;
 
         if (action === 'read') {
+            Ext.applyIf(options.params, this.baseParams);
             doRequest = this.fireEvent('beforeload', this, options);
         }
         else {
             doRequest = this.fireEvent('beforeload', this, options);
         }
         else {
-            // if Writer is configured as listful, force single-recoord rs to be [{}} instead of {}
+            // if Writer is configured as listful, force single-record rs to be [{}] instead of {}
+            // TODO Move listful rendering into DataWriter where the @cfg is defined.  Should be easy now.
             if (this.writer.listful === true && this.restful !== true) {
                 rs = (Ext.isArray(rs)) ? rs : [rs];
             }
             if (this.writer.listful === true && this.restful !== true) {
                 rs = (Ext.isArray(rs)) ? rs : [rs];
             }
@@ -835,10 +872,11 @@ sortInfo: {
             // Send request to proxy.
             var params = Ext.apply({}, options.params, this.baseParams);
             if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
             // Send request to proxy.
             var params = Ext.apply({}, options.params, this.baseParams);
             if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
-                params.xaction = action;
+                params.xaction = action;    // <-- really old, probaby unecessary.
             }
             }
-            // Note:  Up until this point we've been dealing with 'action' as a key from Ext.data.Api.actions.  We'll flip it now
-            // and send the value into DataProxy#request, since it's the value which maps to the DataProxy#api
+            // Note:  Up until this point we've been dealing with 'action' as a key from Ext.data.Api.actions.
+            // We'll flip it now and send the value into DataProxy#request, since it's the value which maps to
+            // the user's configured DataProxy#api
             this.proxy.request(Ext.data.Api.actions[action], rs, params, this.reader, this.createCallback(action, rs), this, options);
         }
         return doRequest;
             this.proxy.request(Ext.data.Api.actions[action], rs, params, this.reader, this.createCallback(action, rs), this, options);
         }
         return doRequest;
@@ -921,7 +959,7 @@ sortInfo: {
         var actions = Ext.data.Api.actions;
         return (action == 'read') ? this.loadRecords : function(data, response, success) {
             // calls: onCreateRecords | onUpdateRecords | onDestroyRecords
         var actions = Ext.data.Api.actions;
         return (action == 'read') ? this.loadRecords : function(data, response, success) {
             // calls: onCreateRecords | onUpdateRecords | onDestroyRecords
-            this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, data);
+            this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
             // If success === false here, exception will have been called in DataProxy
             if (success === true) {
                 this.fireEvent('write', this, action, data, response, rs);
             // If success === false here, exception will have been called in DataProxy
             if (success === true) {
                 this.fireEvent('write', this, action, data, response, rs);
@@ -992,7 +1030,7 @@ sortInfo: {
     // @protected onDestroyRecords proxy callback for destroy action
     onDestroyRecords : function(success, rs, data) {
         // splice each rec out of this.removed
     // @protected onDestroyRecords proxy callback for destroy action
     onDestroyRecords : function(success, rs, data) {
         // splice each rec out of this.removed
-        rs = (rs instanceof Ext.data.Record) ? [rs] : rs;
+        rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
         for (var i=0,len=rs.length;i<len;i++) {
             this.removed.splice(this.removed.indexOf(rs[i]), 1);
         }
         for (var i=0,len=rs.length;i<len;i++) {
             this.removed.splice(this.removed.indexOf(rs[i]), 1);
         }
@@ -1047,7 +1085,7 @@ sortInfo: {
                 this.data = this.snapshot;
                 delete this.snapshot;
             }
                 this.data = this.snapshot;
                 delete this.snapshot;
             }
-            this.data.clear();
+            this.clearData();
             this.data.addAll(r);
             this.totalLength = t;
             this.applySort();
             this.data.addAll(r);
             this.totalLength = t;
             this.applySort();
@@ -1443,15 +1481,18 @@ sortInfo: {
     },
 
     // private
     },
 
     // private
-    onMetaChange : function(meta, rtype, o){
-        this.recordType = rtype;
-        this.fields = rtype.prototype.fields;
+    onMetaChange : function(meta){
+        this.recordType = this.reader.recordType;
+        this.fields = this.recordType.prototype.fields;
         delete this.snapshot;
         delete this.snapshot;
-        if(meta.sortInfo){
-            this.sortInfo = meta.sortInfo;
+        if(this.reader.meta.sortInfo){
+            this.sortInfo = this.reader.meta.sortInfo;
         }else if(this.sortInfo  && !this.fields.get(this.sortInfo.field)){
             delete this.sortInfo;
         }
         }else if(this.sortInfo  && !this.fields.get(this.sortInfo.field)){
             delete this.sortInfo;
         }
+        if(this.writer){
+            this.writer.meta = this.reader.meta;
+        }
         this.modified = [];
         this.fireEvent('metachange', this, this.reader.meta);
     },
         this.modified = [];
         this.fireEvent('metachange', this, this.reader.meta);
     },
@@ -1498,6 +1539,6 @@ Ext.apply(Ext.data.Store.Error.prototype, {
     }
 });
 
     }
 });
 
-</pre>    \r
-</body>\r
+</pre>
+</body>
 </html>
\ No newline at end of file
 </html>
\ No newline at end of file