</head>
<body onload="prettyPrint();">
<pre class="prettyprint lang-js">/*!
- * Ext JS Library 3.2.0
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * licensing@extjs.com
- * http://www.extjs.com/license
+ * Ext JS Library 3.3.1
+ * Copyright(c) 2006-2010 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
*/
<div id="cls-Ext.data.Store"></div>/**
* @class Ext.data.Store
dir : 'dir'
},
- <div id="prop-Ext.data.Store-isDestroyed"></div>/**
- * @property isDestroyed
- * @type Boolean
- * True if the store has been destroyed already. Read only
- */
- isDestroyed: false,
-
- <div id="prop-Ext.data.Store-hasMultiSort"></div>/**
- * @property hasMultiSort
- * @type Boolean
- * True if this store is currently sorted by more than one field/direction combination.
- */
+ isDestroyed: false,
hasMultiSort: false,
// private
batchKey : '_ext_batch_',
constructor : function(config){
+ <div id="prop-Ext.data.Store-multiSort"></div>/**
+ * @property multiSort
+ * @type Boolean
+ * True if this store is currently sorted by more than one field/direction combination.
+ */
+
+ <div id="prop-Ext.data.Store-isDestroyed"></div>/**
+ * @property isDestroyed
+ * @type Boolean
+ * True if the store has been destroyed already. Read only
+ */
+
this.data = new Ext.util.MixedCollection(false);
this.data.getKey = function(o){
return o.id;
};
-
+
// temporary removed-records cache
this.removed = [];
* @event clear
* Fires when the data cache has been cleared.
* @param {Store} this
- * @param {Record[]} The records that were cleared.
+ * @param {Record[]} records The records that were cleared.
*/
'clear',
<div id="event-Ext.data.Store-exception"></div>/**
* @param {Ext.data.Record[]} records An Array of Ext.data.Record objects
* to add to the cache. See {@link #recordType}.
*/
- add : function(records){
+ add : function(records) {
+ var i, len, record, index;
+
records = [].concat(records);
- if(records.length < 1){
+ if (records.length < 1) {
return;
}
- for(var i = 0, len = records.length; i < len; i++){
- records[i].join(this);
+
+ for (i = 0, len = records.length; i < len; i++) {
+ record = records[i];
+
+ record.join(this);
+
+ if (record.dirty || record.phantom) {
+ this.modified.push(record);
+ }
}
- var index = this.data.length;
+
+ index = this.data.length;
this.data.addAll(records);
- if(this.snapshot){
+
+ if (this.snapshot) {
this.snapshot.addAll(records);
}
+
this.fireEvent('add', this, records, index);
},
var index = this.findInsertIndex(record);
this.insert(index, record);
},
+
+ /**
+ * @private
+ * Update a record within the store with a new reference
+ */
+ doUpdate : function(rec){
+ this.data.replace(rec.id, rec);
+ if(this.snapshot){
+ this.snapshot.replace(rec.id, rec);
+ }
+ this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
+ },
<div id="method-Ext.data.Store-remove"></div>/**
* Remove Records from the Store and fires the {@link #remove} event.
Ext.each(record, function(r){
this.remove(r);
}, this);
+ return;
}
var index = this.data.indexOf(record);
if(index > -1){
* @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){
+ insert : function(index, records) {
+ var i, len, record;
+
records = [].concat(records);
- for(var i = 0, len = records.length; i < len; i++){
- this.data.insert(index, records[i]);
- records[i].join(this);
+ for (i = 0, len = records.length; i < len; i++) {
+ record = records[i];
+
+ this.data.insert(index + i, record);
+ record.join(this);
+
+ if (record.dirty || record.phantom) {
+ this.modified.push(record);
+ }
}
- if(this.snapshot){
+
+ if (this.snapshot) {
this.snapshot.addAll(records);
}
+
this.fireEvent('add', this, records, index);
},
},
/**
+ * @private
* Should not be used directly. Store#add will call this automatically if a Writer is set
* @param {Object} store
- * @param {Object} rs
+ * @param {Object} records
* @param {Object} index
- * @private
*/
- createRecords : function(store, rs, index) {
- for (var i = 0, len = rs.length; i < len; i++) {
- if (rs[i].phantom && rs[i].isValid()) {
- rs[i].markDirty(); // <-- Mark new records dirty
- this.modified.push(rs[i]); // <-- add to modified
+ createRecords : function(store, records, index) {
+ var modified = this.modified,
+ length = records.length,
+ record, i;
+
+ for (i = 0; i < length; i++) {
+ record = records[i];
+
+ if (record.phantom && record.isValid()) {
+ record.markDirty(); // <-- Mark new records dirty (Ed: why?)
+
+ if (modified.indexOf(record) == -1) {
+ modified.push(record);
+ }
}
}
if (this.autoSave === true) {
len,
trans,
batch,
- data = {};
+ data = {},
+ i;
// DESTROY: First check for removed records. Records in this.removed are guaranteed non-phantoms. @see Store#remove
if(this.removed.length){
queue.push(['destroy', this.removed]);
if(rs.length){
// CREATE: Next check for phantoms within rs. splice-off and execute create.
var phantoms = [];
- for(var i = rs.length-1; i >= 0; i--){
+ for(i = rs.length-1; i >= 0; i--){
if(rs[i].phantom === true){
var rec = rs.splice(i, 1).shift();
if(rec.isValid()){
len = queue.length;
if(len){
batch = ++this.batchCounter;
- for(var i = 0; i < len; ++i){
+ for(i = 0; i < len; ++i){
trans = queue[i];
data[trans[0]] = trans[1];
}
if(this.fireEvent('beforesave', this, data) !== false){
- for(var i = 0; i < len; ++i){
+ for(i = 0; i < len; ++i){
trans = queue[i];
this.doTransaction(trans[0], trans[1], batch);
}
var b = this.batches,
key = this.batchKey + batch,
o = b[key],
- data,
arr;
// private
// Called as a callback by the Reader during a load operation.
loadRecords : function(o, options, success){
+ var i, len;
+
if (this.isDestroyed === true) {
return;
}
if(this.pruneModifiedRecords){
this.modified = [];
}
- for(var i = 0, len = r.length; i < len; i++){
+ for(i = 0, len = r.length; i < len; i++){
r[i].join(this);
}
if(this.snapshot){
this.applySort();
this.fireEvent('datachanged', this);
}else{
- this.totalLength = Math.max(t, this.data.length+r.length);
- this.add(r);
+ var toAdd = [],
+ rec,
+ cnt = 0;
+ for(i = 0, len = r.length; i < len; ++i){
+ rec = r[i];
+ if(this.indexOfId(rec.id) > -1){
+ this.doUpdate(rec);
+ }else{
+ toAdd.push(rec);
+ ++cnt;
+ }
+ }
+ this.totalLength = Math.max(t, this.data.length + cnt);
+ this.add(toAdd);
}
this.fireEvent('load', this, r, options);
if(options.callback){
}
},
- <div id="method-Ext.data.Store-createSortFunction"></div>/**
+ /**
+ * @private
* Creates and returns a function which sorts an array by the given field and direction
* @param {String} field The field to create the sorter for
* @param {String} direction The direction to sort by (defaults to "ASC")
*/
singleSort: function(fieldName, dir) {
var field = this.fields.get(fieldName);
- if (!field) return false;
+ if (!field) {
+ return false;
+ }
var name = field.name,
sortInfo = this.sortInfo || null,
this.applySort();
this.fireEvent('datachanged', this);
}
+ return true;
},
<div id="method-Ext.data.Store-multiSort"></div>/**
}
<div id="prop-Ext.data.Store-multiSortInfo"></div>/**
+ * Object containing overall sort direction and an ordered array of sorter configs used when sorting on multiple fields
* @property multiSortInfo
* @type Object
- * Object containing overall sort direction and an ordered array of sorter configs used when sorting on multiple fields
*/
this.multiSortInfo = {
sorters : sorters,
};
},
- <div id="method-Ext.data.Store-createMultipleFilterFn"></div>/**
+ /**
+ * @private
* Given an array of filter functions (each with optional scope), constructs and returns a single function that returns
* the result of all of the filters ANDed together
* @param {Array} filters The array of filter objects (each object should contain an 'fn' and optional scope)
* Single filter example:
* store.filter('name', 'Ed', true, true); //finds all records containing the substring 'Ed'
* Multiple filter example:
+ * <pre><code>
* store.filter([
* {
* property : 'name',
* scope: this
* }
* ]);
+ * </code></pre>
* @param {String|Array} field A field on your records, or an array containing multiple filter options
* @param {String/RegExp} value Either a string that the field should begin with, or a RegExp to test
* against the field.
* @param {Boolean} exactMatch True to force exact match (^ and $ characters added to the regex). Defaults to false. Ignored if anyMatch is true.
*/
filter : function(property, value, anyMatch, caseSensitive, exactMatch){
+ var fn;
//we can accept an array of filter objects, or a single filter object - normalize them here
if (Ext.isObject(property)) {
property = [property];
filters.push({fn: func, scope: scope});
}
- var fn = this.createMultipleFilterFn(filters);
+ fn = this.createMultipleFilterFn(filters);
} else {
//classic single property filter
- var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
+ fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
}
return fn ? this.filterBy(fn) : this.clearFilter();
*/
filterBy : function(fn, scope){
this.snapshot = this.snapshot || this.data;
- this.data = this.queryBy(fn, scope||this);
+ this.data = this.queryBy(fn, scope || this);
this.fireEvent('datachanged', this);
},
* 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();
+ var modified = this.modified.slice(0),
+ length = modified.length,
+ i;
+
+ for (i = 0; i < length; i++){
+ modified[i].commit();
}
+
+ this.modified = [];
+ this.removed = [];
},
<div id="method-Ext.data.Store-rejectChanges"></div>/**
* {@link Ext.data.Record#reject Reject} outstanding changes on all {@link #getModifiedRecords modified records}.
*/
- rejectChanges : function(){
- var m = this.modified.slice(0);
- this.modified = [];
- for(var i = 0, len = m.length; i < len; i++){
- m[i].reject();
+ rejectChanges : function() {
+ var modified = this.modified.slice(0),
+ removed = this.removed.slice(0).reverse(),
+ mLength = modified.length,
+ rLength = removed.length,
+ i;
+
+ for (i = 0; i < mLength; i++) {
+ modified[i].reject();
}
- var m = this.removed.slice(0).reverse();
- this.removed = [];
- for(var i = 0, len = m.length; i < len; i++){
- this.insert(m[i].lastIndex||0, m[i]);
- m[i].reject();
+
+ for (i = 0; i < rLength; i++) {
+ this.insert(removed[i].lastIndex || 0, removed[i]);
+ removed[i].reject();
}
+
+ this.modified = [];
+ this.removed = [];
},
// private