📄 jsonpathstore.js
字号:
var meta={}; //default parent to the store root; var pInfo ={item:this._data}; if (options){ if (options.parent){ options.item = options.parent; } dojo.mixin(pInfo, options); } if (this.idAttribute && !data[this.idAttribute]){ if (this.requireId){throw new Error("requireId is enabled, new items must have an id defined to be added");} if (this.autoIdentity){ var newId = this.autoIdPrefix + this._autoId++; data[this.idAttribute]=newId; meta["autoId"]=true; } } if (!pInfo && !pInfo.attribute && !this.idAttribute && !data[this.idAttribute]){ throw new Error("Adding a new item requires, at a minumum, either the pInfo information, including the pInfo.attribute, or an id on the item in the field identified by idAttribute"); } //pInfo.parent = this._correctReference(pInfo.parent); //if there is no parent info supplied, default to the store root //and add to the pInfo.attribute or if that doestn' exist create an //attribute with the same name as the new items ID if(!pInfo.attribute){pInfo.attribute = data[this.idAttribute]} pInfo.oldValue = this._trimItem(pInfo.item[pInfo.attribute]); if (dojo.isArray(pInfo.item[pInfo.attribute])){ this._setDirty(pInfo.item); pInfo.item[pInfo.attribute].push(data); }else{ this._setDirty(pInfo.item); pInfo.item[pInfo.attribute]=data; } pInfo.newValue = pInfo.item[pInfo.attribute]; //add this item to the index if(data[this.idAttribute]){this.index[data[this.idAttribute]]=data} this._updateMeta(data, meta) //keep track of all references in the store so we can delete them as necessary this._addReference(data, pInfo); //mark this new item as dirty this._setDirty(data); //Notification API this.onNew(data, pInfo); //returns the original item, now decorated with some meta info return data; }, _addReference: function(item, pInfo){ // summary // adds meta information to an item containing a reference id // so that references can be deleted as necessary, when passed // only a string, the string for parent info, it will only // it will be treated as a string reference //console.log("_addReference: ", item, pInfo); var rid = '_ref_' + this._referenceId++; if (!item[this.metaLabel]["referenceIds"]){ item[this.metaLabel]["referenceIds"]=[]; } item[this.metaLabel]["referenceIds"].push(rid); this._references[rid] = pInfo; }, deleteItem: function(item){ // summary // deletes item and any references to that item from the store. // If the desire is to delete only one reference, unsetAttribute or // setValue is the way to go. item = this._correctReference(item); console.log("Item: ", item); if (this.isItem(item)){ while(item[this.metaLabel]["referenceIds"].length>0){ console.log("refs map: " , this._references); console.log("item to delete: ", item); var rid = item[this.metaLabel]["referenceIds"].pop(); var pInfo = this._references[rid]; console.log("deleteItem(): ", pInfo, pInfo.parent); parentItem = pInfo.parent; var attribute = pInfo.attribute; if(parentItem && parentItem[attribute] && !dojo.isArray(parentItem[attribute])){ this._setDirty(parentItem); this.unsetAttribute(parentItem, attribute); delete parentItem[attribute]; } if (dojo.isArray(parentItem[attribute])){ console.log("Parent is array"); var oldValue = this._trimItem(parentItem[attribute]); var found=false; for (var i=0; i<parentItem[attribute].length && !found;i++){ if (parentItem[attribute][i][this.metaLabel]===item[this.metaLabel]){ found=true; } } if (found){ this._setDirty(parentItem); var del = parentItem[attribute].splice(i-1,1); delete del; } var newValue = this._trimItem(parentItem[attribute]); this.onSet(parentItem,attribute,oldValue,newValue); } delete this._references[rid]; } this.onDelete(item); delete item; } }, _setDirty: function(item){ // summary: // adds an item to the list of dirty items. This item // contains a reference to the item itself as well as a // cloned and trimmed version of old item for use with // revert. //if an item is already in the list of dirty items, don't add it again //or it will overwrite the premodification data set. for (var i=0; i<this._dirtyItems.length; i++){ if (item[this.idAttribute]==this._dirtyItems[i][this.idAttribute]){ return; } } this._dirtyItems.push({item: item, old: this._trimItem(item)}); this._updateMeta(item, {isDirty: true}); }, setValue: function(item, attribute, value){ // summary: // sets 'attribute' on 'item' to 'value' item = this._correctReference(item); this._setDirty(item); var old = item[attribute] | undefined; item[attribute]=value; this.onSet(item,attribute,old,value); }, setValues: function(item, attribute, values){ // summary: // sets 'attribute' on 'item' to 'value' value // must be an array. item = this._correctReference(item); if (!dojo.isArray(values)){throw new Error("setValues expects to be passed an Array object as its value");} this._setDirty(item); var old = item[attribute] || null; item[attribute]=values this.onSet(item,attribute,old,values); }, unsetAttribute: function(item, attribute){ // summary: // unsets 'attribute' on 'item' item = this._correctReference(item); this._setDirty(item); var old = item[attribute]; delete item[attribute]; this.onSet(item,attribute,old,null); }, save: function(kwArgs){ // summary: // Takes an optional set of keyword Args with // some save options. Currently only format with options // being "raw" or "json". This function goes through // the dirty item lists, clones and trims the item down so that // the items children are not part of the data (the children are replaced // with reference objects). This data is compiled into a single array, the dirty objects // are all marked as clean, and the new data is then passed on to the onSave handler. var data = []; if (!kwArgs){kwArgs={}} while (this._dirtyItems.length > 0){ var item = this._dirtyItems.pop()["item"]; var t = this._trimItem(item); var d; switch(kwArgs.format){ case "json": d = dojo.toJson(t); break; case "raw": default: d = t; } data.push(d); this._markClean(item); } this.onSave(data); }, _markClean: function(item){ // summary // remove this meta information marking an item as "dirty" if (item && item[this.metaLabel] && item[this.metaLabel]["isDirty"]){ delete item[this.metaLabel]["isDirty"]; } }, revert: function(){ // summary // returns any modified data to its original state prior to a save(); while (this._dirtyItems.length>0){ var d = this._dirtyItems.pop(); this._mixin(d.item, d.old); } this.onRevert(); }, _mixin: function(target, data){ // summary: // specialized mixin that hooks up objects in the store where references are identified. if (dojo.isObject(data)){ if (dojo.isArray(data)){ while(target.length>0){target.pop();} for (var i=0; i<data.length;i++){ if (dojo.isObject(data[i])){ if (dojo.isArray(data[i])){ var mix=[]; }else{ var mix={}; if (data[i][this.metaLabel] && data[i][this.metaLabel]["type"] && data[i][this.metaLabel]["type"]=='reference'){ target[i]=this.index[data[i][this.idAttribute]]; continue; } } this._mixin(mix, data[i]); target.push(mix); }else{ target.push(data[i]); } } }else{ for (var i in target){ if (i in data){continue;} delete target[i]; } for (var i in data){ if (dojo.isObject(data[i])){ if (dojo.isArray(data[i])){ var mix=[]; }else{ if (data[i][this.metaLabel] && data[i][this.metaLabel]["type"] && data[i][this.metaLabel]["type"]=='reference'){ target[i]=this.index[data[i][this.idAttribute]]; continue; } var mix={}; } this._mixin(mix, data[i]); target[i]=mix; }else{ target[i]=data[i]; } } } } }, isDirty: function(item){ // summary // returns true if the item is marked as dirty. item = this._correctReference(item); return item && item[this.metaLabel] && item[this.metaLabel]["isDirty"]; }, _createReference: function(item){ // summary // Create a small reference object that can be used to replace // child objects during a trim var obj={}; obj[this.metaLabel]={ type:'reference' }; obj[this.idAttribute]=item[this.idAttribute]; return obj; }, _trimItem: function(item){ //summary: // copy an item recursively stoppying at other items that have id's // and replace them with a refrence object; var copy; if (dojo.isArray(item)){ copy = []; for (var i=0; i<item.length;i++){ if (dojo.isArray(item[i])){ copy.push(this._trimItem(item[i])) }else if (dojo.isObject(item[i])){ if (item[i]["getFullYear"]){ copy.push(dojo.date.stamp.toISOString(item[i])); }else if (item[i][this.idAttribute]){ copy.push(this._createReference(item[i])); }else{ copy.push(this._trimItem(item[i])); } } else { copy.push(item[i]); } } return copy; } if (dojo.isObject(item)){ copy = {}; for (var attr in item){ if (!item[attr]){ copy[attr]=undefined;continue;} if (dojo.isArray(item[attr])){ copy[attr] = this._trimItem(item[attr]); }else if (dojo.isObject(item[attr])){ if (item[attr]["getFullYear"]){ copy[attr] = dojo.date.stamp.toISOString(item[attr]); }else if(item[attr][this.idAttribute]){ copy[attr]=this._createReference(item[attr]); } else { copy[attr]=this._trimItem(item[attr]); } } else { copy[attr]=item[attr]; } } return copy; } }, //Notifcation Support onSet: function(){ }, onNew: function(){ }, onDelete: function(){ }, onSave: function(items){ // summary: // notification of the save event..not part of the notification api, // but probably should be. //console.log("onSave() ", items); }, onRevert: function(){ // summary: // notification of the revert event..not part of the notification api, // but probably should be. } });//setup an alias to byId, is there a better way to do this?dojox.data.jsonPathStore.byId=dojox.data.jsonPathStore.fetchItemByIdentity;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -