📄 jsonreststore.js
字号:
defResult.callback(results); } else { defResult = this.service(query); } defResult.addCallback(function(results){ delete dojox._newId; // cleanup if (args.onBegin){ args["onBegin"].call(_this, results.length, args); } _this._walk(results,function(obj,i,value){ if (value instanceof Array){ for (var i in _this._arrayModifyingMethods){ if (!value[i]._augmented){ value[i] = _this._arrayModifyingMethods[i]; } } } }); if (args.onItem){ for (var i=0; i<results.length;i++){ args["onItem"].call(_this, results[i], args); } } if (args.onComplete){ args["onComplete"].call(_this, results, args); } return results; }); defResult.addErrback(args.onError); return args; }, getFeatures: function(){ // summary: // return the store feature set return { "dojo.data.api.Read": true, "dojo.data.api.Identity": true, "dojo.data.api.Write": true, "dojo.data.api.Notification": true } }, getLabel: function(item){ // summary // returns the label for an item. Just gets the "label" attribute. // return this.getValue(item,"label"); }, getLabelAttributes: function(item){ // summary: // returns an array of attributes that are used to create the label of an item return ["label"]; }, sort: function(a,b){ console.log("TODO::implement default sort algo"); }, //Identity API Support getIdentity: function(item){ // summary // returns the identity of an item or throws // a not found error. var prefix = this.service.serviceName + '/'; if (!item._id){// generate a good random id item._id = prefix + Math.random().toString(16).substring(2,14)+Math.random().toString(16).substring(2,14); } if (item._id.substring(0,prefix.length) != prefix){ throw Error("Identity attribute not found"); } return item._id.substring(prefix.length); }, getIdentityAttributes: function(item){ // summary: // returns the attributes which are used to make up the // identity of an item. Basically returns this.idAttribute return [this.idAttribute]; }, fetchItemByIdentity: function(args){ // summary: // fetch an item by its identity. fetch and fetchItemByIdentity work exactly the same return this.fetch(args); }, //Write API Support newItem: function(data, parentInfo){ // summary: // adds a new item to the store at the specified point. // Takes two parameters, data, and options. // // data: /* object */ // The data to be added in as an item. // parentInfo: // An optional javascript object defining what item is the parent of this item (in a hierarchical store. Not all stores do hierarchical items), // and what attribute of that parent to assign the new item to. If this is present, and the attribute specified // is a multi-valued attribute, it will append this item into the array of values for that attribute. The structure // of the object is as follows: // { // parent: someItem, // } // or // { // parentId: someItemId, // } if (this.service._schema && this.service._schema.clazz && data.constructor != this.service._schema.clazz) data = dojo.mixin(new this.service._schema.clazz,data); this.getIdentity(data); this._getParent(parentInfo).push(data); // essentially what newItem really means this.onNew(data); return data; }, _getParent : function(parentInfo){ var parentId = (parentInfo && parentInfo.parentId) || this.parentId || ''; var parent = (parentInfo && parentInfo.parent) || dojox.rpc._index[this.service.serviceName + '/' + parentId] || []; if (!parent._id){ parent._id = this.service.serviceName + '/' + parentId; this._setDirty(parent); // set it dirty so it will be post } return parent; }, deleteItem: function(item,/*array*/parentInfo){ // summary // deletes item any references to that item from the store. // // item: // item to delete // // removeFrom: This an item or items from which to remove references to this object. This store does not record references, // so if this parameter the entire object graph from load items will be searched for references. Providing this parameter // is vastly faster. An empty object or truthy primitive can be passed if no references need to be removed // If the desire is to delete only one reference, unsetAttribute or // setValue is the way to go. if (this.isItem(item)) this._deletedItems.push(item); var _this = this; this._walk(((parentInfo || this.parentId) && this._getParent(parentInfo)) || dojox.rpc._index,function(obj,i,val){ if (obj[i] === item){ // find a reference to this object if (_this.isItem(obj)){ if (isNaN(i) || !obj.splice){ // remove a property _this.unsetAttribute(obj,i); delete obj[i]; } else {// remove an array entry obj.splice(i,1); } } } }); this.onDelete(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. var i; if (!item._id) return; //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 (i=0; i<this._dirtyItems.length; i++){ if (item==this._dirtyItems[i].item){ return; } } var old = item instanceof Array ? [] : {}; for (i in item) if (item.hasOwnProperty(i)) old[i] = item[i]; this._dirtyItems.push({item: item, old: old}); }, setValue: function(item, attribute, value){ // summary: // sets 'attribute' on 'item' to 'value' var old = item[attribute]; if (old != value){ this._setDirty(item); 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. 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]; item[attribute]=values; this.onSet(item,attribute,old,values); }, unsetAttribute: function(item, attribute){ // summary: // unsets 'attribute' on 'item' this._setDirty(item); var old = item[attribute]; delete item[attribute]; this.onSet(item,attribute,old,undefined); }, _commitAppend: function(listId,item){ return this.service.post(listId,item); }, save: function(kwArgs){ // summary: // Saves the dirty data using REST Ajax methods var data = []; var left = 0; // this is how many changes are remaining to be received from the server var _this = this; function finishOne(){ if (!(--left)) _this.onSave(data); } while (this._dirtyItems.length > 0){ var dirty = this._dirtyItems.pop(); var item = dirty.item; var append = false; left++; var deferred; if (item instanceof Array && dirty.old instanceof Array){ // see if we can just append the item with a post append = true; for (var i = 0, l = dirty.old.length; i < l; i++){ if (item[i] != dirty.old[i]){ append = false; } } if (append){ // if we can, we will do posts to add from here for (;i<item.length;i++){ deferred = this._commitAppend(this.getIdentity(item),item[i]); deferred.addCallback(finishOne); } } } if (!append){ deferred = this.service.put(this.getIdentity(item),item); deferred.addCallback(finishOne); } data.push(item); } while (this._deletedItems.length > 0){ left++; this.service['delete'](this.getIdentity(this._deletedItems.pop())).addCallback(finishOne); } }, revert: function(){ // summary // returns any modified data to its original state prior to a save(); while (this._dirtyItems.length>0){ var i; var d = this._dirtyItems.pop(); for (i in d.old){ d.item[i] = d.old[i]; } for (i in d.item){ if (!d.old.hasOwnProperty(i)) delete d.item[i] } } this.onRevert(); }, isDirty: function(item){ // summary // returns true if the item is marked as dirty. for (var i=0, l=this._dirtyItems.length; i<l; i++){ if (this._dirtyItems[i]==item){return true}; } }, //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. } });}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -