Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / docs / source / AbstractStore.html
1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-data.AbstractStore'>/**
2 </span> * @author Ed Spencer
3  * @class Ext.data.AbstractStore
4  *
5  * &lt;p&gt;AbstractStore is a superclass of {@link Ext.data.Store} and {@link Ext.data.TreeStore}. It's never used directly,
6  * but offers a set of methods used by both of those subclasses.&lt;/p&gt;
7  * 
8  * &lt;p&gt;We've left it here in the docs for reference purposes, but unless you need to make a whole new type of Store, what
9  * you're probably looking for is {@link Ext.data.Store}. If you're still interested, here's a brief description of what 
10  * AbstractStore is and is not.&lt;/p&gt;
11  * 
12  * &lt;p&gt;AbstractStore provides the basic configuration for anything that can be considered a Store. It expects to be 
13  * given a {@link Ext.data.Model Model} that represents the type of data in the Store. It also expects to be given a 
14  * {@link Ext.data.proxy.Proxy Proxy} that handles the loading of data into the Store.&lt;/p&gt;
15  * 
16  * &lt;p&gt;AbstractStore provides a few helpful methods such as {@link #load} and {@link #sync}, which load and save data
17  * respectively, passing the requests through the configured {@link #proxy}. Both built-in Store subclasses add extra
18  * behavior to each of these functions. Note also that each AbstractStore subclass has its own way of storing data - 
19  * in {@link Ext.data.Store} the data is saved as a flat {@link Ext.util.MixedCollection MixedCollection}, whereas in
20  * {@link Ext.data.TreeStore TreeStore} we use a {@link Ext.data.Tree} to maintain the data's hierarchy.&lt;/p&gt;
21  * 
22  * TODO: Update these docs to explain about the sortable and filterable mixins.
23  * &lt;p&gt;Finally, AbstractStore provides an API for sorting and filtering data via its {@link #sorters} and {@link #filters}
24  * {@link Ext.util.MixedCollection MixedCollections}. Although this functionality is provided by AbstractStore, there's a
25  * good description of how to use it in the introduction of {@link Ext.data.Store}.
26  * 
27  */
28 Ext.define('Ext.data.AbstractStore', {
29     requires: ['Ext.util.MixedCollection', 'Ext.data.Operation', 'Ext.util.Filter'],
30     
31     mixins: {
32         observable: 'Ext.util.Observable',
33         sortable: 'Ext.util.Sortable'
34     },
35     
36     statics: {
37         create: function(store){
38             if (!store.isStore) {
39                 if (!store.type) {
40                     store.type = 'store';
41                 }
42                 store = Ext.createByAlias('store.' + store.type, store);
43             }
44             return store;
45         }    
46     },
47     
48     remoteSort  : false,
49     remoteFilter: false,
50
51 <span id='Ext-data.AbstractStore-cfg-proxy'>    /**
52 </span>     * @cfg {String/Ext.data.proxy.Proxy/Object} proxy The Proxy to use for this Store. This can be either a string, a config
53      * object or a Proxy instance - see {@link #setProxy} for details.
54      */
55
56 <span id='Ext-data.AbstractStore-cfg-autoLoad'>    /**
57 </span>     * @cfg {Boolean/Object} autoLoad If data is not specified, and if autoLoad is true or an Object, this store's load method
58      * is automatically called after creation. If the value of autoLoad is an Object, this Object will be passed to the store's
59      * load method. Defaults to false.
60      */
61     autoLoad: false,
62
63 <span id='Ext-data.AbstractStore-cfg-autoSync'>    /**
64 </span>     * @cfg {Boolean} autoSync True to automatically sync the Store with its Proxy after every edit to one of its Records.
65      * Defaults to false.
66      */
67     autoSync: false,
68
69 <span id='Ext-data.AbstractStore-property-batchUpdateMode'>    /**
70 </span>     * Sets the updating behavior based on batch synchronization. 'operation' (the default) will update the Store's
71      * internal representation of the data after each operation of the batch has completed, 'complete' will wait until
72      * the entire batch has been completed before updating the Store's data. 'complete' is a good choice for local
73      * storage proxies, 'operation' is better for remote proxies, where there is a comparatively high latency.
74      * @property batchUpdateMode
75      * @type String
76      */
77     batchUpdateMode: 'operation',
78
79 <span id='Ext-data.AbstractStore-property-filterOnLoad'>    /**
80 </span>     * If true, any filters attached to this Store will be run after loading data, before the datachanged event is fired.
81      * Defaults to true, ignored if {@link #remoteFilter} is true
82      * @property filterOnLoad
83      * @type Boolean
84      */
85     filterOnLoad: true,
86
87 <span id='Ext-data.AbstractStore-property-sortOnLoad'>    /**
88 </span>     * If true, any sorters attached to this Store will be run after loading data, before the datachanged event is fired.
89      * Defaults to true, igored if {@link #remoteSort} is true
90      * @property sortOnLoad
91      * @type Boolean
92      */
93     sortOnLoad: true,
94
95 <span id='Ext-data.AbstractStore-property-implicitModel'>    /**
96 </span>     * True if a model was created implicitly for this Store. This happens if a fields array is passed to the Store's constructor
97      * instead of a model constructor or name.
98      * @property implicitModel
99      * @type Boolean
100      * @private
101      */
102     implicitModel: false,
103
104 <span id='Ext-data.AbstractStore-property-defaultProxyType'>    /**
105 </span>     * The string type of the Proxy to create if none is specified. This defaults to creating a {@link Ext.data.proxy.Memory memory proxy}.
106      * @property defaultProxyType
107      * @type String
108      */
109     defaultProxyType: 'memory',
110
111 <span id='Ext-data.AbstractStore-property-isDestroyed'>    /**
112 </span>     * True if the Store has already been destroyed via {@link #destroyStore}. If this is true, the reference to Store should be deleted
113      * as it will not function correctly any more.
114      * @property isDestroyed
115      * @type Boolean
116      */
117     isDestroyed: false,
118
119     isStore: true,
120
121 <span id='Ext-data.AbstractStore-cfg-storeId'>    /**
122 </span>     * @cfg {String} storeId Optional unique identifier for this store. If present, this Store will be registered with 
123      * the {@link Ext.data.StoreManager}, making it easy to reuse elsewhere. Defaults to undefined.
124      */
125     
126 <span id='Ext-data.AbstractStore-cfg-fields'>    /**
127 </span>     * @cfg {Array} fields
128      * This may be used in place of specifying a {@link #model} configuration. The fields should be a 
129      * set of {@link Ext.data.Field} configuration objects. The store will automatically create a {@link Ext.data.Model}
130      * with these fields. In general this configuration option should be avoided, it exists for the purposes of
131      * backwards compatibility. For anything more complicated, such as specifying a particular id property or
132      * assocations, a {@link Ext.data.Model} should be defined and specified for the {@link #model} config.
133      */
134
135     sortRoot: 'data',
136     
137     //documented above
138     constructor: function(config) {
139         var me = this;
140         
141         me.addEvents(
142 <span id='Ext-data.AbstractStore-event-add'>            /**
143 </span>             * @event add
144              * Fired when a Model instance has been added to this Store
145              * @param {Ext.data.Store} store The store
146              * @param {Array} records The Model instances that were added
147              * @param {Number} index The index at which the instances were inserted
148              */
149             'add',
150
151 <span id='Ext-data.AbstractStore-event-remove'>            /**
152 </span>             * @event remove
153              * Fired when a Model instance has been removed from this Store
154              * @param {Ext.data.Store} store The Store object
155              * @param {Ext.data.Model} record The record that was removed
156              * @param {Number} index The index of the record that was removed
157              */
158             'remove',
159             
160 <span id='Ext-data.AbstractStore-event-update'>            /**
161 </span>             * @event update
162              * Fires when a Record has been updated
163              * @param {Store} this
164              * @param {Ext.data.Model} record The Model instance that was updated
165              * @param {String} operation The update operation being performed. Value may be one of:
166              * &lt;pre&gt;&lt;code&gt;
167                Ext.data.Model.EDIT
168                Ext.data.Model.REJECT
169                Ext.data.Model.COMMIT
170              * &lt;/code&gt;&lt;/pre&gt;
171              */
172             'update',
173
174 <span id='Ext-data.AbstractStore-event-datachanged'>            /**
175 </span>             * @event datachanged
176              * Fires whenever the records in the Store have changed in some way - this could include adding or removing records,
177              * or updating the data in existing records
178              * @param {Ext.data.Store} this The data store
179              */
180             'datachanged',
181
182 <span id='Ext-data.AbstractStore-event-beforeload'>            /**
183 </span>             * @event beforeload
184              * Event description
185              * @param {Ext.data.Store} store This Store
186              * @param {Ext.data.Operation} operation The Ext.data.Operation object that will be passed to the Proxy to load the Store
187              */
188             'beforeload',
189
190 <span id='Ext-data.AbstractStore-event-load'>            /**
191 </span>             * @event load
192              * Fires whenever the store reads data from a remote data source.
193              * @param {Ext.data.Store} this
194              * @param {Array} records An array of records
195              * @param {Boolean} successful True if the operation was successful.
196              */
197             'load',
198
199 <span id='Ext-data.AbstractStore-event-beforesync'>            /**
200 </span>             * @event beforesync
201              * Called before a call to {@link #sync} is executed. Return false from any listener to cancel the synv
202              * @param {Object} options Hash of all records to be synchronized, broken down into create, update and destroy
203              */
204             'beforesync',
205 <span id='Ext-data.AbstractStore-event-clear'>            /**
206 </span>             * @event clear
207              * Fired after the {@link #removeAll} method is called.
208              * @param {Ext.data.Store} this
209              */
210             'clear'
211         );
212         
213         Ext.apply(me, config);
214
215 <span id='Ext-data.AbstractStore-property-removed'>        /**
216 </span>         * Temporary cache in which removed model instances are kept until successfully synchronised with a Proxy,
217          * at which point this is cleared.
218          * @private
219          * @property removed
220          * @type Array
221          */
222         me.removed = [];
223
224         me.mixins.observable.constructor.apply(me, arguments);
225         me.model = Ext.ModelManager.getModel(config.model || me.model);
226
227 <span id='Ext-data.AbstractStore-property-modelDefaults'>        /**
228 </span>         * @property modelDefaults
229          * @type Object
230          * @private
231          * A set of default values to be applied to every model instance added via {@link #insert} or created via {@link #create}.
232          * This is used internally by associations to set foreign keys and other fields. See the Association classes source code
233          * for examples. This should not need to be used by application developers.
234          */
235         Ext.applyIf(me, {
236             modelDefaults: {}
237         });
238
239         //Supports the 3.x style of simply passing an array of fields to the store, implicitly creating a model
240         if (!me.model &amp;&amp; me.fields) {
241             me.model = Ext.define('Ext.data.Store.ImplicitModel-' + (me.storeId || Ext.id()), {
242                 extend: 'Ext.data.Model',
243                 fields: me.fields,
244                 proxy: me.proxy || me.defaultProxyType
245             });
246
247             delete me.fields;
248
249             me.implicitModel = true;
250         }
251
252         //ensures that the Proxy is instantiated correctly
253         me.setProxy(config.proxy || me.proxy || me.model.getProxy());
254
255         if (me.id &amp;&amp; !me.storeId) {
256             me.storeId = me.id;
257             delete me.id;
258         }
259
260         if (me.storeId) {
261             Ext.data.StoreManager.register(me);
262         }
263         
264         me.mixins.sortable.initSortable.call(me);        
265         
266 <span id='Ext-data.AbstractStore-property-filters'>        /**
267 </span>         * The collection of {@link Ext.util.Filter Filters} currently applied to this Store
268          * @property filters
269          * @type Ext.util.MixedCollection
270          */
271         me.filters = Ext.create('Ext.util.MixedCollection');
272         me.filters.addAll(me.decodeFilters(config.filters));
273     },
274
275 <span id='Ext-data.AbstractStore-method-setProxy'>    /**
276 </span>     * Sets the Store's Proxy by string, config object or Proxy instance
277      * @param {String|Object|Ext.data.proxy.Proxy} proxy The new Proxy, which can be either a type string, a configuration object
278      * or an Ext.data.proxy.Proxy instance
279      * @return {Ext.data.proxy.Proxy} The attached Proxy object
280      */
281     setProxy: function(proxy) {
282         var me = this;
283         
284         if (proxy instanceof Ext.data.proxy.Proxy) {
285             proxy.setModel(me.model);
286         } else {
287             if (Ext.isString(proxy)) {
288                 proxy = {
289                     type: proxy    
290                 };
291             }
292             Ext.applyIf(proxy, {
293                 model: me.model
294             });
295             
296             proxy = Ext.createByAlias('proxy.' + proxy.type, proxy);
297         }
298         
299         me.proxy = proxy;
300         
301         return me.proxy;
302     },
303
304 <span id='Ext-data.AbstractStore-method-getProxy'>    /**
305 </span>     * Returns the proxy currently attached to this proxy instance
306      * @return {Ext.data.proxy.Proxy} The Proxy instance
307      */
308     getProxy: function() {
309         return this.proxy;
310     },
311
312     //saves any phantom records
313     create: function(data, options) {
314         var me = this,
315             instance = Ext.ModelManager.create(Ext.applyIf(data, me.modelDefaults), me.model.modelName),
316             operation;
317         
318         options = options || {};
319
320         Ext.applyIf(options, {
321             action : 'create',
322             records: [instance]
323         });
324
325         operation = Ext.create('Ext.data.Operation', options);
326
327         me.proxy.create(operation, me.onProxyWrite, me);
328         
329         return instance;
330     },
331
332     read: function() {
333         return this.load.apply(this, arguments);
334     },
335
336     onProxyRead: Ext.emptyFn,
337
338     update: function(options) {
339         var me = this,
340             operation;
341         options = options || {};
342
343         Ext.applyIf(options, {
344             action : 'update',
345             records: me.getUpdatedRecords()
346         });
347
348         operation = Ext.create('Ext.data.Operation', options);
349
350         return me.proxy.update(operation, me.onProxyWrite, me);
351     },
352
353 <span id='Ext-data.AbstractStore-method-onProxyWrite'>    /**
354 </span>     * @private
355      * Callback for any write Operation over the Proxy. Updates the Store's MixedCollection to reflect
356      * the updates provided by the Proxy
357      */
358     onProxyWrite: function(operation) {
359         var me = this,
360             success = operation.wasSuccessful(),
361             records = operation.getRecords();
362
363         switch (operation.action) {
364             case 'create':
365                 me.onCreateRecords(records, operation, success);
366                 break;
367             case 'update':
368                 me.onUpdateRecords(records, operation, success);
369                 break;
370             case 'destroy':
371                 me.onDestroyRecords(records, operation, success);
372                 break;
373         }
374
375         if (success) {
376             me.fireEvent('write', me, operation);
377             me.fireEvent('datachanged', me);
378         }
379         //this is a callback that would have been passed to the 'create', 'update' or 'destroy' function and is optional
380         Ext.callback(operation.callback, operation.scope || me, [records, operation, success]);
381     },
382
383
384     //tells the attached proxy to destroy the given records
385     destroy: function(options) {
386         var me = this,
387             operation;
388             
389         options = options || {};
390
391         Ext.applyIf(options, {
392             action : 'destroy',
393             records: me.getRemovedRecords()
394         });
395
396         operation = Ext.create('Ext.data.Operation', options);
397
398         return me.proxy.destroy(operation, me.onProxyWrite, me);
399     },
400
401 <span id='Ext-data.AbstractStore-method-onBatchOperationComplete'>    /**
402 </span>     * @private
403      * Attached as the 'operationcomplete' event listener to a proxy's Batch object. By default just calls through
404      * to onProxyWrite.
405      */
406     onBatchOperationComplete: function(batch, operation) {
407         return this.onProxyWrite(operation);
408     },
409
410 <span id='Ext-data.AbstractStore-method-onBatchComplete'>    /**
411 </span>     * @private
412      * Attached as the 'complete' event listener to a proxy's Batch object. Iterates over the batch operations
413      * and updates the Store's internal data MixedCollection.
414      */
415     onBatchComplete: function(batch, operation) {
416         var me = this,
417             operations = batch.operations,
418             length = operations.length,
419             i;
420
421         me.suspendEvents();
422
423         for (i = 0; i &lt; length; i++) {
424             me.onProxyWrite(operations[i]);
425         }
426
427         me.resumeEvents();
428
429         me.fireEvent('datachanged', me);
430     },
431
432     onBatchException: function(batch, operation) {
433         // //decide what to do... could continue with the next operation
434         // batch.start();
435         //
436         // //or retry the last operation
437         // batch.retry();
438     },
439
440 <span id='Ext-data.AbstractStore-method-filterNew'>    /**
441 </span>     * @private
442      * Filter function for new records.
443      */
444     filterNew: function(item) {
445         // only want phantom records that are valid
446         return item.phantom === true &amp;&amp; item.isValid();
447     },
448
449 <span id='Ext-data.AbstractStore-method-getNewRecords'>    /**
450 </span>     * Returns all Model instances that are either currently a phantom (e.g. have no id), or have an ID but have not
451      * yet been saved on this Store (this happens when adding a non-phantom record from another Store into this one)
452      * @return {Array} The Model instances
453      */
454     getNewRecords: function() {
455         return [];
456     },
457
458 <span id='Ext-data.AbstractStore-method-getUpdatedRecords'>    /**
459 </span>     * Returns all Model instances that have been updated in the Store but not yet synchronized with the Proxy
460      * @return {Array} The updated Model instances
461      */
462     getUpdatedRecords: function() {
463         return [];
464     },
465
466 <span id='Ext-data.AbstractStore-method-filterUpdated'>    /**
467 </span>     * @private
468      * Filter function for updated records.
469      */
470     filterUpdated: function(item) {
471         // only want dirty records, not phantoms that are valid
472         return item.dirty === true &amp;&amp; item.phantom !== true &amp;&amp; item.isValid();
473     },
474
475     //returns any records that have been removed from the store but not yet destroyed on the proxy
476     getRemovedRecords: function() {
477         return this.removed;
478     },
479
480     filter: function(filters, value) {
481
482     },
483
484 <span id='Ext-data.AbstractStore-method-decodeFilters'>    /**
485 </span>     * @private
486      * Normalizes an array of filter objects, ensuring that they are all Ext.util.Filter instances
487      * @param {Array} filters The filters array
488      * @return {Array} Array of Ext.util.Filter objects
489      */
490     decodeFilters: function(filters) {
491         if (!Ext.isArray(filters)) {
492             if (filters === undefined) {
493                 filters = [];
494             } else {
495                 filters = [filters];
496             }
497         }
498
499         var length = filters.length,
500             Filter = Ext.util.Filter,
501             config, i;
502
503         for (i = 0; i &lt; length; i++) {
504             config = filters[i];
505
506             if (!(config instanceof Filter)) {
507                 Ext.apply(config, {
508                     root: 'data'
509                 });
510
511                 //support for 3.x style filters where a function can be defined as 'fn'
512                 if (config.fn) {
513                     config.filterFn = config.fn;
514                 }
515
516                 //support a function to be passed as a filter definition
517                 if (typeof config == 'function') {
518                     config = {
519                         filterFn: config
520                     };
521                 }
522
523                 filters[i] = new Filter(config);
524             }
525         }
526
527         return filters;
528     },
529
530     clearFilter: function(supressEvent) {
531
532     },
533
534     isFiltered: function() {
535
536     },
537
538     filterBy: function(fn, scope) {
539
540     },
541     
542 <span id='Ext-data.AbstractStore-method-sync'>    /**
543 </span>     * Synchronizes the Store with its Proxy. This asks the Proxy to batch together any new, updated
544      * and deleted records in the store, updating the Store's internal representation of the records
545      * as each operation completes.
546      */
547     sync: function() {
548         var me        = this,
549             options   = {},
550             toCreate  = me.getNewRecords(),
551             toUpdate  = me.getUpdatedRecords(),
552             toDestroy = me.getRemovedRecords(),
553             needsSync = false;
554
555         if (toCreate.length &gt; 0) {
556             options.create = toCreate;
557             needsSync = true;
558         }
559
560         if (toUpdate.length &gt; 0) {
561             options.update = toUpdate;
562             needsSync = true;
563         }
564
565         if (toDestroy.length &gt; 0) {
566             options.destroy = toDestroy;
567             needsSync = true;
568         }
569
570         if (needsSync &amp;&amp; me.fireEvent('beforesync', options) !== false) {
571             me.proxy.batch(options, me.getBatchListeners());
572         }
573     },
574
575
576 <span id='Ext-data.AbstractStore-method-getBatchListeners'>    /**
577 </span>     * @private
578      * Returns an object which is passed in as the listeners argument to proxy.batch inside this.sync.
579      * This is broken out into a separate function to allow for customisation of the listeners
580      * @return {Object} The listeners object
581      */
582     getBatchListeners: function() {
583         var me = this,
584             listeners = {
585                 scope: me,
586                 exception: me.onBatchException
587             };
588
589         if (me.batchUpdateMode == 'operation') {
590             listeners.operationcomplete = me.onBatchOperationComplete;
591         } else {
592             listeners.complete = me.onBatchComplete;
593         }
594
595         return listeners;
596     },
597
598     //deprecated, will be removed in 5.0
599     save: function() {
600         return this.sync.apply(this, arguments);
601     },
602
603 <span id='Ext-data.AbstractStore-method-load'>    /**
604 </span>     * Loads the Store using its configured {@link #proxy}.
605      * @param {Object} options Optional config object. This is passed into the {@link Ext.data.Operation Operation}
606      * object that is created and then sent to the proxy's {@link Ext.data.proxy.Proxy#read} function
607      */
608     load: function(options) {
609         var me = this,
610             operation;
611
612         options = options || {};
613
614         Ext.applyIf(options, {
615             action : 'read',
616             filters: me.filters.items,
617             sorters: me.getSorters()
618         });
619         
620         operation = Ext.create('Ext.data.Operation', options);
621
622         if (me.fireEvent('beforeload', me, operation) !== false) {
623             me.loading = true;
624             me.proxy.read(operation, me.onProxyLoad, me);
625         }
626         
627         return me;
628     },
629
630 <span id='Ext-data.AbstractStore-method-afterEdit'>    /**
631 </span>     * @private
632      * A model instance should call this method on the Store it has been {@link Ext.data.Model#join joined} to.
633      * @param {Ext.data.Model} record The model instance that was edited
634      */
635     afterEdit : function(record) {
636         var me = this;
637         
638         if (me.autoSync) {
639             me.sync();
640         }
641         
642         me.fireEvent('update', me, record, Ext.data.Model.EDIT);
643     },
644
645 <span id='Ext-data.AbstractStore-method-afterReject'>    /**
646 </span>     * @private
647      * A model instance should call this method on the Store it has been {@link Ext.data.Model#join joined} to..
648      * @param {Ext.data.Model} record The model instance that was edited
649      */
650     afterReject : function(record) {
651         this.fireEvent('update', this, record, Ext.data.Model.REJECT);
652     },
653
654 <span id='Ext-data.AbstractStore-method-afterCommit'>    /**
655 </span>     * @private
656      * A model instance should call this method on the Store it has been {@link Ext.data.Model#join joined} to.
657      * @param {Ext.data.Model} record The model instance that was edited
658      */
659     afterCommit : function(record) {
660         this.fireEvent('update', this, record, Ext.data.Model.COMMIT);
661     },
662
663     clearData: Ext.emptyFn,
664
665     destroyStore: function() {
666         var me = this;
667         
668         if (!me.isDestroyed) {
669             if (me.storeId) {
670                 Ext.data.StoreManager.unregister(me);
671             }
672             me.clearData();
673             me.data = null;
674             me.tree = null;
675             // Ext.destroy(this.proxy);
676             me.reader = me.writer = null;
677             me.clearListeners();
678             me.isDestroyed = true;
679
680             if (me.implicitModel) {
681                 Ext.destroy(me.model);
682             }
683         }
684     },
685     
686     doSort: function(sorterFn) {
687         var me = this;
688         if (me.remoteSort) {
689             //the load function will pick up the new sorters and request the sorted data from the proxy
690             me.load();
691         } else {
692             me.data.sortBy(sorterFn);
693             me.fireEvent('datachanged', me);
694         }
695     },
696
697     getCount: Ext.emptyFn,
698
699     getById: Ext.emptyFn,
700     
701 <span id='Ext-data.AbstractStore-property-removeAll'>    /**
702 </span>     * Removes all records from the store. This method does a &quot;fast remove&quot;,
703      * individual remove events are not called. The {@link #clear} event is
704      * fired upon completion.
705      */
706     removeAll: Ext.emptyFn,
707     // individual substores should implement a &quot;fast&quot; remove
708     // and fire a clear event afterwards
709
710 <span id='Ext-data.AbstractStore-method-isLoading'>    /**
711 </span>     * Returns true if the Store is currently performing a load operation
712      * @return {Boolean} True if the Store is currently loading
713      */
714     isLoading: function() {
715         return this.loading;
716      }
717 });
718 </pre></pre></body></html>