X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/source/data/Store.js diff --git a/source/data/Store.js b/source/data/Store.js deleted file mode 100644 index fafd025b..00000000 --- a/source/data/Store.js +++ /dev/null @@ -1,857 +0,0 @@ -/* - * Ext JS Library 2.2.1 - * Copyright(c) 2006-2009, Ext JS, LLC. - * licensing@extjs.com - * - * http://extjs.com/license - */ - -/** - * @class Ext.data.Store - * @extends Ext.util.Observable - * The Store class encapsulates a client side cache of {@link Ext.data.Record Record} - * objects which provide input data for Components such as the {@link Ext.grid.GridPanel GridPanel}, - * the {@link Ext.form.ComboBox ComboBox}, or the {@link Ext.DataView DataView}

- *

A Store object uses its {@link #proxy configured} implementation of {@link Ext.data.DataProxy DataProxy} - * to access a data object unless you call {@link #loadData} directly and pass in your data.

- *

A Store object has no knowledge of the format of the data returned by the Proxy.

- *

A Store object uses its {@link #reader configured} implementation of {@link Ext.data.DataReader DataReader} - * to create {@link Ext.data.Record Record} instances from the data object. These Records - * are cached and made available through accessor functions.

- * @constructor - * Creates a new Store. - * @param {Object} config A config object containing the objects needed for the Store to access data, - * and read the data into Records. - */ -Ext.data.Store = function(config){ - this.data = new Ext.util.MixedCollection(false); - this.data.getKey = function(o){ - return o.id; - }; - /** - * An object containing properties which are used as parameters on any HTTP request. - * This property can be changed after creating the Store to send different parameters. - * @property - */ - this.baseParams = {}; - /** - *

An object containing properties which specify the names of the paging and - * sorting parameters passed to remote servers when loading blocks of data. By default, this - * object takes the following form:


-{
-    start : "start",    // The parameter name which specifies the start row
-    limit : "limit",    // The parameter name which specifies number of rows to return
-    sort : "sort",      // The parameter name which specifies the column to sort on
-    dir : "dir"         // The parameter name which specifies the sort direction
-}
-
- *

The server must produce the requested data block upon receipt of these parameter names. - * If different parameter names are required, this property can be overriden using a configuration - * property.

- *

A {@link Ext.PagingToolbar PagingToolbar} bound to this grid uses this property to determine - * the parameter names to use in its requests. - * @property - */ - this.paramNames = { - "start" : "start", - "limit" : "limit", - "sort" : "sort", - "dir" : "dir" - }; - - if(config && config.data){ - this.inlineData = config.data; - delete config.data; - } - - Ext.apply(this, config); - - if(this.url && !this.proxy){ - this.proxy = new Ext.data.HttpProxy({url: this.url}); - } - - if(this.reader){ // reader passed - if(!this.recordType){ - this.recordType = this.reader.recordType; - } - if(this.reader.onMetaChange){ - this.reader.onMetaChange = this.onMetaChange.createDelegate(this); - } - } - - /** - * The {@link Ext.data.Record Record} constructor as supplied to (or created by) the {@link Ext.data.Reader#Reader Reader}. Read-only. - *

If the Reader was constructed by passing in an Array of field definition objects, instead of an created - * Record constructor it will have {@link Ext.data.Record#create created a constructor} from that Array.

- *

This property may be used to create new Records of the type held in this Store.

- * @property recordType - * @type Function - */ - if(this.recordType){ - /** - * A MixedCollection containing the defined {@link Ext.data.Field Field}s for the Records stored in this Store. Read-only. - * @property fields - * @type Ext.util.MixedCollection - */ - this.fields = this.recordType.prototype.fields; - } - this.modified = []; - - this.addEvents( - /** - * @event datachanged - * Fires when the data cache has changed in a bulk manner (e.g., it has been sorted, filtered, etc.) and a - * widget that is using this Store as a Record cache should refresh its view. - * @param {Store} this - */ - 'datachanged', - /** - * @event metachange - * Fires when this store's reader provides new metadata (fields). This is currently only supported for JsonReaders. - * @param {Store} this - * @param {Object} meta The JSON metadata - */ - 'metachange', - /** - * @event add - * Fires when Records have been added to the Store - * @param {Store} this - * @param {Ext.data.Record[]} records The array of Records added - * @param {Number} index The index at which the record(s) were added - */ - 'add', - /** - * @event remove - * Fires when a Record has been removed from the Store - * @param {Store} this - * @param {Ext.data.Record} record The Record that was removed - * @param {Number} index The index at which the record was removed - */ - 'remove', - /** - * @event update - * Fires when a Record has been updated - * @param {Store} this - * @param {Ext.data.Record} record The Record that was updated - * @param {String} operation The update operation being performed. Value may be one of: - *

- Ext.data.Record.EDIT
- Ext.data.Record.REJECT
- Ext.data.Record.COMMIT
-         * 
- */ - 'update', - /** - * @event clear - * Fires when the data cache has been cleared. - * @param {Store} this - */ - 'clear', - /** - * @event beforeload - * Fires before a request is made for a new data object. If the beforeload handler returns false - * the load action will be canceled. - * @param {Store} this - * @param {Object} options The loading options that were specified (see {@link #load} for details) - */ - 'beforeload', - /** - * @event load - * Fires after a new set of Records has been loaded. - * @param {Store} this - * @param {Ext.data.Record[]} records The Records that were loaded - * @param {Object} options The loading options that were specified (see {@link #load} for details) - */ - 'load', - /** - * @event loadexception - * Fires if an exception occurs in the Proxy during loading. - * Called with the signature of the Proxy's "loadexception" event. - */ - 'loadexception' - ); - - if(this.proxy){ - this.relayEvents(this.proxy, ["loadexception"]); - } - - this.sortToggle = {}; - if(this.sortInfo){ - this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction); - } - - Ext.data.Store.superclass.constructor.call(this); - - if(this.storeId || this.id){ - Ext.StoreMgr.register(this); - } - if(this.inlineData){ - this.loadData(this.inlineData); - delete this.inlineData; - }else if(this.autoLoad){ - this.load.defer(10, this, [ - typeof this.autoLoad == 'object' ? - this.autoLoad : undefined]); - } -}; -Ext.extend(Ext.data.Store, Ext.util.Observable, { - /** - * @cfg {String} storeId If passed, the id to use to register with the StoreMgr - */ - /** - * @cfg {String} url If passed, an HttpProxy is created for the passed URL - */ - /** - * @cfg {Boolean/Object} autoLoad If passed, this store's load method is automatically called after creation with the autoLoad object - */ - /** - * @cfg {Ext.data.DataProxy} proxy The Proxy object which provides access to a data object. - */ - /** - * @cfg {Array} data Inline data to be loaded when the store is initialized. - */ - /** - * @cfg {Ext.data.DataReader} reader The DataReader object which processes the data object and returns - * an Array of Ext.data.Record objects which are cached keyed by their id property. - */ - /** - * @cfg {Object} baseParams An object containing properties which are to be sent as parameters - * on any HTTP request - */ - /** - * @cfg {Object} sortInfo A config object in the format: {field: "fieldName", direction: "ASC|DESC"} to - * specify the sort order in the request of a remote Store's {@link #load} operation. Note that for - * local sorting, the direction property is case-sensitive. - */ - /** - * @cfg {boolean} remoteSort True if sorting is to be handled by requesting the - * Proxy to provide a refreshed version of the data object in sorted order, as - * opposed to sorting the Record cache in place (defaults to false). - *

If remote sorting is specified, then clicking on a column header causes the - * current page to be requested from the server with the addition of the following - * two parameters: - *

- */ - remoteSort : false, - - /** - * @cfg {boolean} pruneModifiedRecords True to clear all modified record information each time the store is - * loaded or when a record is removed. (defaults to false). - */ - pruneModifiedRecords : false, - - /** - * Contains the last options object used as the parameter to the load method. See {@link #load} - * for the details of what this may contain. This may be useful for accessing any params which - * were used to load the current Record cache. - * @property - */ - lastOptions : null, - - destroy : function(){ - if(this.storeId || this.id){ - Ext.StoreMgr.unregister(this); - } - this.data = null; - this.purgeListeners(); - }, - - /** - * Add Records to the Store and fires the {@link #add} event. - * @param {Ext.data.Record[]} records An Array of Ext.data.Record objects to add to the cache. - */ - add : function(records){ - records = [].concat(records); - if(records.length < 1){ - return; - } - for(var i = 0, len = records.length; i < len; i++){ - records[i].join(this); - } - var index = this.data.length; - this.data.addAll(records); - if(this.snapshot){ - this.snapshot.addAll(records); - } - this.fireEvent("add", this, records, index); - }, - - /** - * (Local sort only) Inserts the passed Record into the Store at the index where it - * should go based on the current sort information. - * @param {Ext.data.Record} record - */ - addSorted : function(record){ - var index = this.findInsertIndex(record); - this.insert(index, record); - }, - - /** - * Remove a Record from the Store and fires the {@link #remove} event. - * @param {Ext.data.Record} record The Ext.data.Record object to remove from the cache. - */ - remove : function(record){ - var index = this.data.indexOf(record); - this.data.removeAt(index); - if(this.pruneModifiedRecords){ - this.modified.remove(record); - } - if(this.snapshot){ - this.snapshot.remove(record); - } - this.fireEvent("remove", this, record, index); - }, - - /** - * Remove a Record from the Store at the specified index. Fires the {@link #remove} event. - * @param {Number} index The index of the record to remove. - */ - removeAt : function(index){ - this.remove(this.getAt(index)); - }, - - /** - * Remove all Records from the Store and fires the {@link #clear} event. - */ - removeAll : function(){ - this.data.clear(); - if(this.snapshot){ - this.snapshot.clear(); - } - if(this.pruneModifiedRecords){ - this.modified = []; - } - this.fireEvent("clear", this); - }, - - /** - * Inserts Records into the Store at the given index and fires the {@link #add} event. - * @param {Number} index The start index at which to insert the passed Records. - * @param {Ext.data.Record[]} records An Array of Ext.data.Record objects to add to the cache. - */ - insert : function(index, records){ - records = [].concat(records); - for(var i = 0, len = records.length; i < len; i++){ - this.data.insert(index, records[i]); - records[i].join(this); - } - this.fireEvent("add", this, records, index); - }, - - /** - * Get the index within the cache of the passed Record. - * @param {Ext.data.Record} record The Ext.data.Record object to find. - * @return {Number} The index of the passed Record. Returns -1 if not found. - */ - indexOf : function(record){ - return this.data.indexOf(record); - }, - - /** - * Get the index within the cache of the Record with the passed id. - * @param {String} id The id of the Record to find. - * @return {Number} The index of the Record. Returns -1 if not found. - */ - indexOfId : function(id){ - return this.data.indexOfKey(id); - }, - - /** - * Get the Record with the specified id. - * @param {String} id The id of the Record to find. - * @return {Ext.data.Record} The Record with the passed id. Returns undefined if not found. - */ - getById : function(id){ - return this.data.key(id); - }, - - /** - * Get the Record at the specified index. - * @param {Number} index The index of the Record to find. - * @return {Ext.data.Record} The Record at the passed index. Returns undefined if not found. - */ - getAt : function(index){ - return this.data.itemAt(index); - }, - - /** - * Returns a range of Records between specified indices. - * @param {Number} startIndex (optional) The starting index (defaults to 0) - * @param {Number} endIndex (optional) The ending index (defaults to the last Record in the Store) - * @return {Ext.data.Record[]} An array of Records - */ - getRange : function(start, end){ - return this.data.getRange(start, end); - }, - - // private - storeOptions : function(o){ - o = Ext.apply({}, o); - delete o.callback; - delete o.scope; - this.lastOptions = o; - }, - - /** - * Loads the Record cache from the configured Proxy using the configured Reader. - *

If using remote paging, then the first load call must specify the start - * and limit properties in the options.params property to establish the initial - * position within the dataset, and the number of Records to cache on each read from the Proxy.

- *

It is important to note that for remote data sources, loading is asynchronous, - * and this call will return before the new data has been loaded. Perform any post-processing - * in a callback function, or in a "load" event handler.

- * @param {Object} options An object containing properties which control loading options: - * @return {Boolean} Whether the load fired (if beforeload failed). - */ - load : function(options){ - options = options || {}; - if(this.fireEvent("beforeload", this, options) !== false){ - this.storeOptions(options); - var p = Ext.apply(options.params || {}, this.baseParams); - if(this.sortInfo && this.remoteSort){ - var pn = this.paramNames; - p[pn["sort"]] = this.sortInfo.field; - p[pn["dir"]] = this.sortInfo.direction; - } - this.proxy.load(p, this.reader, this.loadRecords, this, options); - return true; - } else { - return false; - } - }, - - /** - *

Reloads the Record cache from the configured Proxy using the configured Reader and - * the options from the last load operation performed.

- *

It is important to note that for remote data sources, loading is asynchronous, - * and this call will return before the new data has been loaded. Perform any post-processing - * in a callback function, or in a "load" event handler.

- * @param {Object} options (optional) An object containing loading options which may override the options - * used in the last load operation. See {@link #load} for details (defaults to null, in which case - * the most recently used options are reused). - */ - reload : function(options){ - this.load(Ext.applyIf(options||{}, this.lastOptions)); - }, - - // private - // Called as a callback by the Reader during a load operation. - loadRecords : function(o, options, success){ - if(!o || success === false){ - if(success !== false){ - this.fireEvent("load", this, [], options); - } - if(options.callback){ - options.callback.call(options.scope || this, [], options, false); - } - return; - } - var r = o.records, t = o.totalRecords || r.length; - if(!options || options.add !== true){ - if(this.pruneModifiedRecords){ - this.modified = []; - } - for(var i = 0, len = r.length; i < len; i++){ - r[i].join(this); - } - if(this.snapshot){ - this.data = this.snapshot; - delete this.snapshot; - } - this.data.clear(); - this.data.addAll(r); - this.totalLength = t; - this.applySort(); - this.fireEvent("datachanged", this); - }else{ - this.totalLength = Math.max(t, this.data.length+r.length); - this.add(r); - } - this.fireEvent("load", this, r, options); - if(options.callback){ - options.callback.call(options.scope || this, r, options, true); - } - }, - - /** - * Loads data from a passed data block and fires the {@link #load} event. A Reader which understands the format of the data - * must have been configured in the constructor. - * @param {Object} data The data block from which to read the Records. The format of the data expected - * is dependent on the type of Reader that is configured and should correspond to that Reader's readRecords parameter. - * @param {Boolean} add (Optional) True to add the new Records rather than replace the existing cache. Remember that - * Records in a Store are keyed by their {@link Ext.data.Record#id id}, so added Records with ids which are already present in - * the Store will replace existing Records. Records with new, unique ids will be added. - */ - loadData : function(o, append){ - var r = this.reader.readRecords(o); - this.loadRecords(r, {add: append}, true); - }, - - /** - * Gets the number of cached records. - *

If using paging, this may not be the total size of the dataset. If the data object - * used by the Reader contains the dataset size, then the {@link #getTotalCount} function returns - * the dataset size.

- * @return {Number} The number of Records in the Store's cache. - */ - getCount : function(){ - return this.data.length || 0; - }, - - /** - * Gets the total number of records in the dataset as returned by the server. - *

If using paging, for this to be accurate, the data object used by the Reader must contain - * the dataset size. For remote data sources, this is provided by a query on the server.

- * @return {Number} The number of Records as specified in the data object passed to the Reader - * by the Proxy - *

This value is not updated when changing the contents of the Store locally.

- */ - getTotalCount : function(){ - return this.totalLength || 0; - }, - - /** - * Returns an object describing the current sort state of this Store. - * @return {Object} The sort state of the Store. An object with two properties: - */ - getSortState : function(){ - return this.sortInfo; - }, - - // private - applySort : function(){ - if(this.sortInfo && !this.remoteSort){ - var s = this.sortInfo, f = s.field; - this.sortData(f, s.direction); - } - }, - - // private - sortData : function(f, direction){ - direction = direction || 'ASC'; - var st = this.fields.get(f).sortType; - var fn = function(r1, r2){ - var v1 = st(r1.data[f]), v2 = st(r2.data[f]); - return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); - }; - this.data.sort(direction, fn); - if(this.snapshot && this.snapshot != this.data){ - this.snapshot.sort(direction, fn); - } - }, - - /** - * Sets the default sort column and order to be used by the next load operation. - * @param {String} fieldName The name of the field to sort by. - * @param {String} dir (optional) The sort order, "ASC" or "DESC" (case-sensitive, defaults to "ASC") - */ - setDefaultSort : function(field, dir){ - dir = dir ? dir.toUpperCase() : "ASC"; - this.sortInfo = {field: field, direction: dir}; - this.sortToggle[field] = dir; - }, - - /** - * Sort the Records. - * If remote sorting is used, the sort is performed on the server, and the cache is - * reloaded. If local sorting is used, the cache is sorted internally. - * @param {String} fieldName The name of the field to sort by. - * @param {String} dir (optional) The sort order, "ASC" or "DESC" (case-sensitive, defaults to "ASC") - */ - sort : function(fieldName, dir){ - var f = this.fields.get(fieldName); - if(!f){ - return false; - } - if(!dir){ - if(this.sortInfo && this.sortInfo.field == f.name){ // toggle sort dir - dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC"); - }else{ - dir = f.sortDir; - } - } - var st = (this.sortToggle) ? this.sortToggle[f.name] : null; - var si = (this.sortInfo) ? this.sortInfo : null; - - this.sortToggle[f.name] = dir; - this.sortInfo = {field: f.name, direction: dir}; - if(!this.remoteSort){ - this.applySort(); - this.fireEvent("datachanged", this); - }else{ - if (!this.load(this.lastOptions)) { - if (st) { - this.sortToggle[f.name] = st; - } - if (si) { - this.sortInfo = si; - } - } - } - }, - - /** - * Calls the specified function for each of the Records in the cache. - * @param {Function} fn The function to call. The Record is passed as the first parameter. - * Returning false aborts and exits the iteration. - * @param {Object} scope (optional) The scope in which to call the function (defaults to the Record). - */ - each : function(fn, scope){ - this.data.each(fn, scope); - }, - - /** - * Gets all records modified since the last commit. Modified records are persisted across load operations - * (e.g., during paging). - * @return {Ext.data.Record[]} An array of Records containing outstanding modifications. - */ - getModifiedRecords : function(){ - return this.modified; - }, - - // private - createFilterFn : function(property, value, anyMatch, caseSensitive){ - if(Ext.isEmpty(value, false)){ - return false; - } - value = this.data.createValueMatcher(value, anyMatch, caseSensitive); - return function(r){ - return value.test(r.data[property]); - }; - }, - - /** - * Sums the value of property for each record between start and end and returns the result. - * @param {String} property A field on your records - * @param {Number} start The record index to start at (defaults to 0) - * @param {Number} end The last record index to include (defaults to length - 1) - * @return {Number} The sum - */ - sum : function(property, start, end){ - var rs = this.data.items, v = 0; - start = start || 0; - end = (end || end === 0) ? end : rs.length-1; - - for(var i = start; i <= end; i++){ - v += (rs[i].data[property] || 0); - } - return v; - }, - - /** - * Filter the records by a specified property. - * @param {String} field A field on your records - * @param {String/RegExp} value Either a string that the field - * should begin with, or a RegExp to test against the field. - * @param {Boolean} anyMatch (optional) True to match any part not just the beginning - * @param {Boolean} caseSensitive (optional) True for case sensitive comparison - */ - filter : function(property, value, anyMatch, caseSensitive){ - var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); - return fn ? this.filterBy(fn) : this.clearFilter(); - }, - - /** - * Filter by a function. The specified function will be called for each - * Record in this Store. If the function returns true the Record is included, - * otherwise it is filtered out. - * @param {Function} fn The function to be called. It will be passed the following parameters: - * @param {Object} scope (optional) The scope of the function (defaults to this) - */ - filterBy : function(fn, scope){ - this.snapshot = this.snapshot || this.data; - this.data = this.queryBy(fn, scope||this); - this.fireEvent("datachanged", this); - }, - - /** - * Query the records by a specified property. - * @param {String} field A field on your records - * @param {String/RegExp} value Either a string that the field - * should begin with, or a RegExp to test against the field. - * @param {Boolean} anyMatch (optional) True to match any part not just the beginning - * @param {Boolean} caseSensitive (optional) True for case sensitive comparison - * @return {MixedCollection} Returns an Ext.util.MixedCollection of the matched records - */ - query : function(property, value, anyMatch, caseSensitive){ - var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); - return fn ? this.queryBy(fn) : this.data.clone(); - }, - - /** - * Query the cached records in this Store using a filtering function. The specified function - * will be called with each record in this Store. If the function returns true the record is - * included in the results. - * @param {Function} fn The function to be called. It will be passed the following parameters: - * @param {Object} scope (optional) The scope of the function (defaults to this) - * @return {MixedCollection} Returns an Ext.util.MixedCollection of the matched records - **/ - queryBy : function(fn, scope){ - var data = this.snapshot || this.data; - return data.filterBy(fn, scope||this); - }, - - /** - * Finds the index of the first matching record in this store by a specific property/value. - * @param {String} property A property on your objects - * @param {String/RegExp} value Either a string that the property value - * should begin with, or a RegExp to test against the property. - * @param {Number} startIndex (optional) The index to start searching at - * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning - * @param {Boolean} caseSensitive (optional) True for case sensitive comparison - * @return {Number} The matched index or -1 - */ - find : function(property, value, start, anyMatch, caseSensitive){ - var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); - return fn ? this.data.findIndexBy(fn, null, start) : -1; - }, - - /** - * Find the index of the first matching Record in this Store by a function. - * If the function returns true it is considered a match. - * @param {Function} fn The function to be called. It will be passed the following parameters: - * @param {Object} scope (optional) The scope of the function (defaults to this) - * @param {Number} startIndex (optional) The index to start searching at - * @return {Number} The matched index or -1 - */ - findBy : function(fn, scope, start){ - return this.data.findIndexBy(fn, scope, start); - }, - - /** - * Collects unique values for a particular dataIndex from this store. - * @param {String} dataIndex The property to collect - * @param {Boolean} allowNull (optional) Pass true to allow null, undefined or empty string values - * @param {Boolean} bypassFilter (optional) Pass true to collect from all records, even ones which are filtered - * @return {Array} An array of the unique values - **/ - collect : function(dataIndex, allowNull, bypassFilter){ - var d = (bypassFilter === true && this.snapshot) ? - this.snapshot.items : this.data.items; - var v, sv, r = [], l = {}; - for(var i = 0, len = d.length; i < len; i++){ - v = d[i].data[dataIndex]; - sv = String(v); - if((allowNull || !Ext.isEmpty(v)) && !l[sv]){ - l[sv] = true; - r[r.length] = v; - } - } - return r; - }, - - /** - * Revert to a view of the Record cache with no filtering applied. - * @param {Boolean} suppressEvent If true the filter is cleared silently without notifying listeners - */ - clearFilter : function(suppressEvent){ - if(this.isFiltered()){ - this.data = this.snapshot; - delete this.snapshot; - if(suppressEvent !== true){ - this.fireEvent("datachanged", this); - } - } - }, - - /** - * Returns true if this store is currently filtered - * @return {Boolean} - */ - isFiltered : function(){ - return this.snapshot && this.snapshot != this.data; - }, - - // private - afterEdit : function(record){ - if(this.modified.indexOf(record) == -1){ - this.modified.push(record); - } - this.fireEvent("update", this, record, Ext.data.Record.EDIT); - }, - - // private - afterReject : function(record){ - this.modified.remove(record); - this.fireEvent("update", this, record, Ext.data.Record.REJECT); - }, - - // private - afterCommit : function(record){ - this.modified.remove(record); - this.fireEvent("update", this, record, Ext.data.Record.COMMIT); - }, - - /** - * Commit all Records with outstanding changes. To handle updates for changes, subscribe to the - * Store's "update" event, and perform updating when the third parameter is Ext.data.Record.COMMIT. - */ - commitChanges : function(){ - var m = this.modified.slice(0); - this.modified = []; - for(var i = 0, len = m.length; i < len; i++){ - m[i].commit(); - } - }, - - /** - * Cancel outstanding changes on all changed records. - */ - rejectChanges : function(){ - var m = this.modified.slice(0); - this.modified = []; - for(var i = 0, len = m.length; i < len; i++){ - m[i].reject(); - } - }, - - // private - onMetaChange : function(meta, rtype, o){ - this.recordType = rtype; - this.fields = rtype.prototype.fields; - delete this.snapshot; - this.sortInfo = meta.sortInfo; - this.modified = []; - this.fireEvent('metachange', this, this.reader.meta); - }, - - // private - findInsertIndex : function(record){ - this.suspendEvents(); - var data = this.data.clone(); - this.data.add(record); - this.applySort(); - var index = this.data.indexOf(record); - this.data = data; - this.resumeEvents(); - return index; - } -}); \ No newline at end of file