dojo.data.ItemFileReadStore._getItemsFromLoadedData
dojo.require("dojo.data.ItemFileReadStore");
defined in dojo/data/ItemFileReadStore.js
Function to parse the loaded data into item format and build the internal items array.
Usage
function (/*Object*/ dataObject) (view source)
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 += "_"; } while(allAttributeNames[this._reverseRefMap]){ this._reverseRefMap += "_"; } // 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.isObject(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; } } } if(this.referenceIntegrity){ var refItem = arrayOfValues[j]; if(this.isItem(refItem)){ this._addReferenceToMap(refItem, item, key); } } }else if(this.isItem(value)){ //It's a child item (not one referenced through _reference). //We need to treat this as a referenced item, so it can be cleaned up //in a write store easily. if(this.referenceIntegrity){ this._addReferenceToMap(value, item, key); } } } } } }
parameter | type | description |
---|---|---|
dataObject | Object | The JS data object containing the raw data to convery into item format. |