New file |
0,0 → 1,733 |
if(!dojo._hasResource["dojo.data.ItemFileReadStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dojo.data.ItemFileReadStore"] = true; |
dojo.provide("dojo.data.ItemFileReadStore"); |
|
dojo.require("dojo.data.util.filter"); |
dojo.require("dojo.data.util.simpleFetch"); |
dojo.require("dojo.date.stamp"); |
|
dojo.declare("dojo.data.ItemFileReadStore", null,{ |
// summary: |
// The ItemFileReadStore implements the dojo.data.api.Read API and reads |
// data from JSON files that have contents in this format -- |
// { items: [ |
// { name:'Kermit', color:'green', age:12, friends:['Gonzo', {_reference:{name:'Fozzie Bear'}}]}, |
// { name:'Fozzie Bear', wears:['hat', 'tie']}, |
// { name:'Miss Piggy', pets:'Foo-Foo'} |
// ]} |
// Note that it can also contain an 'identifer' property that specified which attribute on the items |
// in the array of items that acts as the unique identifier for that item. |
// |
constructor: function(/* Object */ keywordParameters){ |
// summary: constructor |
// keywordParameters: {url: String} |
// keywordParameters: {data: jsonObject} |
// keywordParameters: {typeMap: object) |
// The structure of the typeMap object is as follows: |
// { |
// type0: function || object, |
// type1: function || object, |
// ... |
// typeN: function || object |
// } |
// Where if it is a function, it is assumed to be an object constructor that takes the |
// value of _value as the initialization parameters. If it is an object, then it is assumed |
// to be an object of general form: |
// { |
// type: function, //constructor. |
// deserialize: function(value) //The function that parses the value and constructs the object defined by type appropriately. |
// } |
|
this._arrayOfAllItems = []; |
this._arrayOfTopLevelItems = []; |
this._loadFinished = false; |
this._jsonFileUrl = keywordParameters.url; |
this._jsonData = keywordParameters.data; |
this._datatypeMap = keywordParameters.typeMap || {}; |
if(!this._datatypeMap['Date']){ |
//If no default mapping for dates, then set this as default. |
//We use the dojo.date.stamp here because the ISO format is the 'dojo way' |
//of generically representing dates. |
this._datatypeMap['Date'] = { |
type: Date, |
deserialize: function(value){ |
return dojo.date.stamp.fromISOString(value); |
} |
}; |
} |
this._features = {'dojo.data.api.Read':true, 'dojo.data.api.Identity':true}; |
this._itemsByIdentity = null; |
this._storeRefPropName = "_S"; // Default name for the store reference to attach to every item. |
this._itemNumPropName = "_0"; // Default Item Id for isItem to attach to every item. |
this._rootItemPropName = "_RI"; // Default Item Id for isItem to attach to every item. |
this._loadInProgress = false; //Got to track the initial load to prevent duelling loads of the dataset. |
this._queuedFetches = []; |
}, |
|
url: "", // use "" rather than undefined for the benefit of the parser (#3539) |
|
_assertIsItem: function(/* item */ item){ |
// summary: |
// This function tests whether the item passed in is indeed an item in the store. |
// item: |
// The item to test for being contained by the store. |
if(!this.isItem(item)){ |
throw new Error("dojo.data.ItemFileReadStore: Invalid item argument."); |
} |
}, |
|
_assertIsAttribute: function(/* attribute-name-string */ attribute){ |
// summary: |
// This function tests whether the item passed in is indeed a valid 'attribute' like type for the store. |
// attribute: |
// The attribute to test for being contained by the store. |
if(typeof attribute !== "string"){ |
throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument."); |
} |
}, |
|
getValue: function( /* item */ item, |
/* attribute-name-string */ attribute, |
/* value? */ defaultValue){ |
// summary: |
// See dojo.data.api.Read.getValue() |
var values = this.getValues(item, attribute); |
return (values.length > 0)?values[0]:defaultValue; // mixed |
}, |
|
getValues: function(/* item */ item, |
/* attribute-name-string */ attribute){ |
// summary: |
// See dojo.data.api.Read.getValues() |
|
this._assertIsItem(item); |
this._assertIsAttribute(attribute); |
return item[attribute] || []; // Array |
}, |
|
getAttributes: function(/* item */ item){ |
// summary: |
// See dojo.data.api.Read.getAttributes() |
this._assertIsItem(item); |
var attributes = []; |
for(var key in item){ |
// Save off only the real item attributes, not the special id marks for O(1) isItem. |
if((key !== this._storeRefPropName) && (key !== this._itemNumPropName) && (key !== this._rootItemPropName)){ |
attributes.push(key); |
} |
} |
return attributes; // Array |
}, |
|
hasAttribute: function( /* item */ item, |
/* attribute-name-string */ attribute) { |
// summary: |
// See dojo.data.api.Read.hasAttribute() |
return this.getValues(item, attribute).length > 0; |
}, |
|
containsValue: function(/* item */ item, |
/* attribute-name-string */ attribute, |
/* anything */ value){ |
// summary: |
// See dojo.data.api.Read.containsValue() |
var regexp = undefined; |
if(typeof value === "string"){ |
regexp = dojo.data.util.filter.patternToRegExp(value, false); |
} |
return this._containsValue(item, attribute, value, regexp); //boolean. |
}, |
|
_containsValue: function( /* item */ item, |
/* attribute-name-string */ attribute, |
/* anything */ value, |
/* RegExp?*/ regexp){ |
// summary: |
// Internal function for looking at the values contained by the item. |
// description: |
// Internal function for looking at the values contained by the item. This |
// function allows for denoting if the comparison should be case sensitive for |
// strings or not (for handling filtering cases where string case should not matter) |
// |
// item: |
// The data item to examine for attribute values. |
// attribute: |
// The attribute to inspect. |
// value: |
// The value to match. |
// regexp: |
// Optional regular expression generated off value if value was of string type to handle wildcarding. |
// If present and attribute values are string, then it can be used for comparison instead of 'value' |
return dojo.some(this.getValues(item, attribute), function(possibleValue){ |
if(possibleValue !== null && !dojo.isObject(possibleValue) && regexp){ |
if(possibleValue.toString().match(regexp)){ |
return true; // Boolean |
} |
}else if(value === possibleValue){ |
return true; // Boolean |
} |
}); |
}, |
|
isItem: function(/* anything */ something){ |
// summary: |
// See dojo.data.api.Read.isItem() |
if(something && something[this._storeRefPropName] === this){ |
if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){ |
return true; |
} |
} |
return false; // Boolean |
}, |
|
isItemLoaded: function(/* anything */ something){ |
// summary: |
// See dojo.data.api.Read.isItemLoaded() |
return this.isItem(something); //boolean |
}, |
|
loadItem: function(/* object */ keywordArgs){ |
// summary: |
// See dojo.data.api.Read.loadItem() |
this._assertIsItem(keywordArgs.item); |
}, |
|
getFeatures: function(){ |
// summary: |
// See dojo.data.api.Read.getFeatures() |
return this._features; //Object |
}, |
|
getLabel: function(/* item */ item){ |
// summary: |
// See dojo.data.api.Read.getLabel() |
if(this._labelAttr && this.isItem(item)){ |
return this.getValue(item,this._labelAttr); //String |
} |
return undefined; //undefined |
}, |
|
getLabelAttributes: function(/* item */ item){ |
// summary: |
// See dojo.data.api.Read.getLabelAttributes() |
if(this._labelAttr){ |
return [this._labelAttr]; //array |
} |
return null; //null |
}, |
|
_fetchItems: function( /* Object */ keywordArgs, |
/* Function */ findCallback, |
/* Function */ errorCallback){ |
// summary: |
// See dojo.data.util.simpleFetch.fetch() |
var self = this; |
var filter = function(requestArgs, arrayOfItems){ |
var items = []; |
if(requestArgs.query){ |
var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; |
|
//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the |
//same value for each item examined. Much more efficient. |
var regexpList = {}; |
for(var key in requestArgs.query){ |
var value = requestArgs.query[key]; |
if(typeof value === "string"){ |
regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase); |
} |
} |
|
for(var i = 0; i < arrayOfItems.length; ++i){ |
var match = true; |
var candidateItem = arrayOfItems[i]; |
if(candidateItem === null){ |
match = false; |
}else{ |
for(var key in requestArgs.query) { |
var value = requestArgs.query[key]; |
if (!self._containsValue(candidateItem, key, value, regexpList[key])){ |
match = false; |
} |
} |
} |
if(match){ |
items.push(candidateItem); |
} |
} |
findCallback(items, requestArgs); |
}else{ |
// We want a copy to pass back in case the parent wishes to sort the array. |
// We shouldn't allow resort of the internal list, so that multiple callers |
// can get lists and sort without affecting each other. We also need to |
// filter out any null values that have been left as a result of deleteItem() |
// calls in ItemFileWriteStore. |
for(var i = 0; i < arrayOfItems.length; ++i){ |
var item = arrayOfItems[i]; |
if(item !== null){ |
items.push(item); |
} |
} |
findCallback(items, requestArgs); |
} |
}; |
|
if(this._loadFinished){ |
filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions)); |
}else{ |
|
if(this._jsonFileUrl){ |
//If fetches come in before the loading has finished, but while |
//a load is in progress, we have to defer the fetching to be |
//invoked in the callback. |
if(this._loadInProgress){ |
this._queuedFetches.push({args: keywordArgs, filter: filter}); |
}else{ |
this._loadInProgress = true; |
var getArgs = { |
url: self._jsonFileUrl, |
handleAs: "json-comment-optional" |
}; |
var getHandler = dojo.xhrGet(getArgs); |
getHandler.addCallback(function(data){ |
try{ |
self._getItemsFromLoadedData(data); |
self._loadFinished = true; |
self._loadInProgress = false; |
|
filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions)); |
self._handleQueuedFetches(); |
}catch(e){ |
self._loadFinished = true; |
self._loadInProgress = false; |
errorCallback(e, keywordArgs); |
} |
}); |
getHandler.addErrback(function(error){ |
self._loadInProgress = false; |
errorCallback(error, keywordArgs); |
}); |
} |
}else if(this._jsonData){ |
try{ |
this._loadFinished = true; |
this._getItemsFromLoadedData(this._jsonData); |
this._jsonData = null; |
filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions)); |
}catch(e){ |
errorCallback(e, keywordArgs); |
} |
}else{ |
errorCallback(new Error("dojo.data.ItemFileReadStore: No JSON source data was provided as either URL or a nested Javascript object."), keywordArgs); |
} |
} |
}, |
|
_handleQueuedFetches: function(){ |
// summary: |
// Internal function to execute delayed request in the store. |
//Execute any deferred fetches now. |
if (this._queuedFetches.length > 0) { |
for(var i = 0; i < this._queuedFetches.length; i++){ |
var fData = this._queuedFetches[i]; |
var delayedQuery = fData.args; |
var delayedFilter = fData.filter; |
if(delayedFilter){ |
delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions)); |
}else{ |
this.fetchItemByIdentity(delayedQuery); |
} |
} |
this._queuedFetches = []; |
} |
}, |
|
_getItemsArray: function(/*object?*/queryOptions){ |
// summary: |
// Internal function to determine which list of items to search over. |
// queryOptions: The query options parameter, if any. |
if(queryOptions && queryOptions.deep) { |
return this._arrayOfAllItems; |
} |
return this._arrayOfTopLevelItems; |
}, |
|
close: function(/*dojo.data.api.Request || keywordArgs || null */ request){ |
// summary: |
// See dojo.data.api.Read.close() |
}, |
|
_getItemsFromLoadedData: function(/* Object */ dataObject){ |
// summary: |
// Function to parse the loaded data into item format and build the internal items array. |
// description: |
// Function to parse the loaded data into item format and build the internal items array. |
// |
// dataObject: |
// The JS data object containing the raw data to convery into item format. |
// |
// returns: array |
// Array of items in store item format. |
|
// First, we define a couple little utility functions... |
|
function valueIsAnItem(/* anything */ aValue){ |
// summary: |
// Given any sort of value that could be in the raw json data, |
// return true if we should interpret the value as being an |
// item itself, rather than a literal value or a reference. |
// example: |
// | false == valueIsAnItem("Kermit"); |
// | false == valueIsAnItem(42); |
// | false == valueIsAnItem(new Date()); |
// | false == valueIsAnItem({_type:'Date', _value:'May 14, 1802'}); |
// | false == valueIsAnItem({_reference:'Kermit'}); |
// | true == valueIsAnItem({name:'Kermit', color:'green'}); |
// | true == valueIsAnItem({iggy:'pop'}); |
// | true == valueIsAnItem({foo:42}); |
var isItem = ( |
(aValue != null) && |
(typeof aValue == "object") && |
(!dojo.isArray(aValue)) && |
(!dojo.isFunction(aValue)) && |
(aValue.constructor == Object) && |
(typeof aValue._reference == "undefined") && |
(typeof aValue._type == "undefined") && |
(typeof aValue._value == "undefined") |
); |
return isItem; |
} |
|
var self = this; |
function addItemAndSubItemsToArrayOfAllItems(/* Item */ anItem){ |
self._arrayOfAllItems.push(anItem); |
for(var attribute in anItem){ |
var valueForAttribute = anItem[attribute]; |
if(valueForAttribute){ |
if(dojo.isArray(valueForAttribute)){ |
var valueArray = valueForAttribute; |
for(var k = 0; k < valueArray.length; ++k){ |
var singleValue = valueArray[k]; |
if(valueIsAnItem(singleValue)){ |
addItemAndSubItemsToArrayOfAllItems(singleValue); |
} |
} |
}else{ |
if(valueIsAnItem(valueForAttribute)){ |
addItemAndSubItemsToArrayOfAllItems(valueForAttribute); |
} |
} |
} |
} |
} |
|
this._labelAttr = dataObject.label; |
|
// We need to do some transformations to convert the data structure |
// that we read from the file into a format that will be convenient |
// to work with in memory. |
|
// Step 1: Walk through the object hierarchy and build a list of all items |
var i; |
var item; |
this._arrayOfAllItems = []; |
this._arrayOfTopLevelItems = dataObject.items; |
|
for(i = 0; i < this._arrayOfTopLevelItems.length; ++i){ |
item = this._arrayOfTopLevelItems[i]; |
addItemAndSubItemsToArrayOfAllItems(item); |
item[this._rootItemPropName]=true; |
} |
|
// Step 2: Walk through all the attribute values of all the items, |
// and replace single values with arrays. For example, we change this: |
// { name:'Miss Piggy', pets:'Foo-Foo'} |
// into this: |
// { name:['Miss Piggy'], pets:['Foo-Foo']} |
// |
// We also store the attribute names so we can validate our store |
// reference and item id special properties for the O(1) isItem |
var allAttributeNames = {}; |
var key; |
|
for(i = 0; i < this._arrayOfAllItems.length; ++i){ |
item = this._arrayOfAllItems[i]; |
for(key in item){ |
if (key !== this._rootItemPropName) |
{ |
var value = item[key]; |
if(value !== null){ |
if(!dojo.isArray(value)){ |
item[key] = [value]; |
} |
}else{ |
item[key] = [null]; |
} |
} |
allAttributeNames[key]=key; |
} |
} |
|
// Step 3: Build unique property names to use for the _storeRefPropName and _itemNumPropName |
// This should go really fast, it will generally never even run the loop. |
while(allAttributeNames[this._storeRefPropName]){ |
this._storeRefPropName += "_"; |
} |
while(allAttributeNames[this._itemNumPropName]){ |
this._itemNumPropName += "_"; |
} |
|
// Step 4: Some data files specify an optional 'identifier', which is |
// the name of an attribute that holds the identity of each item. |
// If this data file specified an identifier attribute, then build a |
// hash table of items keyed by the identity of the items. |
var arrayOfValues; |
|
var identifier = dataObject.identifier; |
if(identifier){ |
this._itemsByIdentity = {}; |
this._features['dojo.data.api.Identity'] = identifier; |
for(i = 0; i < this._arrayOfAllItems.length; ++i){ |
item = this._arrayOfAllItems[i]; |
arrayOfValues = item[identifier]; |
var identity = arrayOfValues[0]; |
if(!this._itemsByIdentity[identity]){ |
this._itemsByIdentity[identity] = item; |
}else{ |
if(this._jsonFileUrl){ |
throw new Error("dojo.data.ItemFileReadStore: The json data as specified by: [" + this._jsonFileUrl + "] is malformed. Items within the list have identifier: [" + identifier + "]. Value collided: [" + identity + "]"); |
}else if(this._jsonData){ |
throw new Error("dojo.data.ItemFileReadStore: The json data provided by the creation arguments is malformed. Items within the list have identifier: [" + identifier + "]. Value collided: [" + identity + "]"); |
} |
} |
} |
}else{ |
this._features['dojo.data.api.Identity'] = Number; |
} |
|
// Step 5: Walk through all the items, and set each item's properties |
// for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true. |
for(i = 0; i < this._arrayOfAllItems.length; ++i){ |
item = this._arrayOfAllItems[i]; |
item[this._storeRefPropName] = this; |
item[this._itemNumPropName] = i; |
} |
|
// Step 6: We walk through all the attribute values of all the items, |
// looking for type/value literals and item-references. |
// |
// We replace item-references with pointers to items. For example, we change: |
// { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } |
// into this: |
// { name:['Kermit'], friends:[miss_piggy] } |
// (where miss_piggy is the object representing the 'Miss Piggy' item). |
// |
// We replace type/value pairs with typed-literals. For example, we change: |
// { name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] } |
// into this: |
// { name:['Kermit'], born:(new Date('July 18, 1918')) } |
// |
// We also generate the associate map for all items for the O(1) isItem function. |
for(i = 0; i < this._arrayOfAllItems.length; ++i){ |
item = this._arrayOfAllItems[i]; // example: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } |
for(key in item){ |
arrayOfValues = item[key]; // example: [{_reference:{name:'Miss Piggy'}}] |
for(var j = 0; j < arrayOfValues.length; ++j) { |
value = arrayOfValues[j]; // example: {_reference:{name:'Miss Piggy'}} |
if(value !== null && typeof value == "object"){ |
if(value._type && value._value){ |
var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber' |
var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}} |
if(!mappingObj){ |
throw new Error("dojo.data.ItemFileReadStore: in the typeMap constructor arg, no object class was specified for the datatype '" + type + "'"); |
}else if(dojo.isFunction(mappingObj)){ |
arrayOfValues[j] = new mappingObj(value._value); |
}else if(dojo.isFunction(mappingObj.deserialize)){ |
arrayOfValues[j] = mappingObj.deserialize(value._value); |
}else{ |
throw new Error("dojo.data.ItemFileReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function"); |
} |
} |
if(value._reference){ |
var referenceDescription = value._reference; // example: {name:'Miss Piggy'} |
if(dojo.isString(referenceDescription)){ |
// example: 'Miss Piggy' |
// from an item like: { name:['Kermit'], friends:[{_reference:'Miss Piggy'}]} |
arrayOfValues[j] = this._itemsByIdentity[referenceDescription]; |
}else{ |
// example: {name:'Miss Piggy'} |
// from an item like: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] } |
for(var k = 0; k < this._arrayOfAllItems.length; ++k){ |
var candidateItem = this._arrayOfAllItems[k]; |
var found = true; |
for(var refKey in referenceDescription){ |
if(candidateItem[refKey] != referenceDescription[refKey]){ |
found = false; |
} |
} |
if(found){ |
arrayOfValues[j] = candidateItem; |
} |
} |
} |
} |
} |
} |
} |
} |
}, |
|
getIdentity: function(/* item */ item){ |
// summary: |
// See dojo.data.api.Identity.getIdentity() |
var identifier = this._features['dojo.data.api.Identity']; |
if(identifier === Number){ |
return item[this._itemNumPropName]; // Number |
}else{ |
var arrayOfValues = item[identifier]; |
if(arrayOfValues){ |
return arrayOfValues[0]; // Object || String |
} |
} |
return null; // null |
}, |
|
fetchItemByIdentity: function(/* Object */ keywordArgs){ |
// summary: |
// See dojo.data.api.Identity.fetchItemByIdentity() |
|
// Hasn't loaded yet, we have to trigger the load. |
if(!this._loadFinished){ |
var self = this; |
if(this._jsonFileUrl){ |
|
if(this._loadInProgress){ |
this._queuedFetches.push({args: keywordArgs}); |
}else{ |
this._loadInProgress = true; |
var getArgs = { |
url: self._jsonFileUrl, |
handleAs: "json-comment-optional" |
}; |
var getHandler = dojo.xhrGet(getArgs); |
getHandler.addCallback(function(data){ |
var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; |
try{ |
self._getItemsFromLoadedData(data); |
self._loadFinished = true; |
self._loadInProgress = false; |
var item = self._getItemByIdentity(keywordArgs.identity); |
if(keywordArgs.onItem){ |
keywordArgs.onItem.call(scope, item); |
} |
self._handleQueuedFetches(); |
}catch(error){ |
self._loadInProgress = false; |
if(keywordArgs.onError){ |
keywordArgs.onError.call(scope, error); |
} |
} |
}); |
getHandler.addErrback(function(error){ |
self._loadInProgress = false; |
if(keywordArgs.onError){ |
var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; |
keywordArgs.onError.call(scope, error); |
} |
}); |
} |
|
}else if(this._jsonData){ |
// Passed in data, no need to xhr. |
self._getItemsFromLoadedData(self._jsonData); |
self._jsonData = null; |
self._loadFinished = true; |
var item = self._getItemByIdentity(keywordArgs.identity); |
if(keywordArgs.onItem){ |
var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; |
keywordArgs.onItem.call(scope, item); |
} |
} |
}else{ |
// Already loaded. We can just look it up and call back. |
var item = this._getItemByIdentity(keywordArgs.identity); |
if(keywordArgs.onItem){ |
var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; |
keywordArgs.onItem.call(scope, item); |
} |
} |
}, |
|
_getItemByIdentity: function(/* Object */ identity){ |
// summary: |
// Internal function to look an item up by its identity map. |
var item = null; |
if(this._itemsByIdentity){ |
item = this._itemsByIdentity[identity]; |
}else{ |
item = this._arrayOfAllItems[identity]; |
} |
if(item === undefined){ |
item = null; |
} |
return item; // Object |
}, |
|
getIdentityAttributes: function(/* item */ item){ |
// summary: |
// See dojo.data.api.Identity.getIdentifierAttributes() |
|
var identifier = this._features['dojo.data.api.Identity']; |
if(identifier === Number){ |
// If (identifier === Number) it means getIdentity() just returns |
// an integer item-number for each item. The dojo.data.api.Identity |
// spec says we need to return null if the identity is not composed |
// of attributes |
return null; // null |
}else{ |
return [identifier]; // Array |
} |
}, |
|
_forceLoad: function(){ |
// summary: |
// Internal function to force a load of the store if it hasn't occurred yet. This is required |
// for specific functions to work properly. |
var self = this; |
if(this._jsonFileUrl){ |
var getArgs = { |
url: self._jsonFileUrl, |
handleAs: "json-comment-optional", |
sync: true |
}; |
var getHandler = dojo.xhrGet(getArgs); |
getHandler.addCallback(function(data){ |
try{ |
//Check to be sure there wasn't another load going on concurrently |
//So we don't clobber data that comes in on it. If there is a load going on |
//then do not save this data. It will potentially clobber current data. |
//We mainly wanted to sync/wait here. |
//TODO: Revisit the loading scheme of this store to improve multi-initial |
//request handling. |
if (self._loadInProgress !== true && !self._loadFinished) { |
self._getItemsFromLoadedData(data); |
self._loadFinished = true; |
} |
}catch(e){ |
console.log(e); |
throw e; |
} |
}); |
getHandler.addErrback(function(error){ |
throw error; |
}); |
}else if(this._jsonData){ |
self._getItemsFromLoadedData(self._jsonData); |
self._jsonData = null; |
self._loadFinished = true; |
} |
} |
}); |
//Mix in the simple fetch implementation to this class. |
dojo.extend(dojo.data.ItemFileReadStore,dojo.data.util.simpleFetch); |
|
} |