PageRenderTime 42ms CodeModel.GetById 25ms app.highlight 11ms RepoModel.GetById 0ms app.codeStats 0ms

/ext-4.0.7/docs/source/AbstractStore.html

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