📄 sync.js
字号:
// // we are offline -- just record this action// var action = {name: "update", customer: customer};// dojox.off.sync.actions.add(action)// // // persist this customer data into local storage as well// dojox.storage.put(customer.name, customer);// })//// Then, when we go back online, the dojox.off.sync.actions.onReplay event// will fire over and over, once for each action that was recorded while offline://// dojo.connect(dojox.off.sync.actions, "onReplay", function(action, actionLog){// // called once for each action we added while offline, in the order// // they were added// if(action.name == "update"){// var customer = action.customer;// // // call some network service to update this customer// dojo.xhrPost({// url: "updateCustomer.php",// content: {customer: dojo.toJson(customer)},// error: function(err){// actionLog.haltReplay(err);// },// load: function(data){// actionLog.continueReplay();// }// })// }// })//// Note that the actions log is always automatically persisted locally while using it, so// that if the user closes the browser or it crashes the actions will safely be stored// for later replaying.dojo.declare("dojox.off.sync.ActionLog", null, { // entries: Array // An array of our action entries, where each one is simply a custom // object literal that were passed to add() when this action entry // was added. entries: [], // reasonHalted: String // If we halted, the reason why reasonHalted: null, // isReplaying: boolean // If true, we are in the middle of replaying a command log; if false, // then we are not isReplaying: false, // autoSave: boolean // Whether we automatically save the action log after each call to // add(); defaults to true. For applications that are rapidly adding // many action log entries in a short period of time, it can be // useful to set this to false and simply call save() yourself when // you are ready to persist your command log -- otherwise performance // could be slow as the default action is to attempt to persist the // actions log constantly with calls to add(). autoSave: true, add: function(action /* Object */){ /* void */ // summary: // Adds an action to our action log // description: // This method will add an action to our // action log, later to be replayed when we // go from offline to online. 'action' // will be available when this action is // replayed and will be passed to onReplay. // // Example usage: // // dojox.off.sync.log.add({actionName: "create", itemType: "document", // {title: "Message", content: "Hello World"}}); // // The object literal is simply a custom object appropriate // for our application -- it can be anything that preserves the state // of a user action that will be executed when we go back online // and replay this log. In the above example, // "create" is the name of this action; "documents" is the // type of item this command is operating on, such as documents, contacts, // tasks, etc.; and the final argument is the document that was created. if(this.isReplaying){ throw "Programming error: you can not call " + "dojox.off.sync.actions.add() while " + "we are replaying an action log"; } this.entries.push(action); // save our updated state into persistent // storage if(this.autoSave){ this._save(); } }, onReplay: function(action /* Object */, actionLog /* dojox.off.sync.ActionLog */){ /* void */ // summary: // Called when we replay our log, for each of our action // entries. // action: Object // A custom object literal representing an action for this // application, such as // {actionName: "create", item: {title: "message", content: "hello world"}} // actionLog: dojox.off.sync.ActionLog // A reference to the dojox.off.sync.actions log so that developers // can easily call actionLog.continueReplay() or actionLog.haltReplay(). // description: // This callback should be connected to by applications so that // they can sync themselves when we go back online: // // dojo.connect(dojox.off.sync.actions, "onReplay", function(action, actionLog){ // // do something // }) // // When we replay our action log, this callback is called for each // of our action entries in the order they were added. The // 'action' entry that was passed to add() for this action will // also be passed in to onReplay, so that applications can use this information // to do their syncing, such as contacting a server web-service // to create a new item, for example. // // Inside the method you connected to onReplay, you should either call // actionLog.haltReplay(reason) if an error occurred and you would like to halt // action replaying or actionLog.continueReplay() to have the action log // continue replaying its log and proceed to the next action; // the reason you must call these is the action you execute inside of // onAction will probably be asynchronous, since it will be talking on // the network, and you should call one of these two methods based on // the result of your network call. }, length: function(){ /* Number */ // summary: // Returns the length of this // action log return this.entries.length; }, haltReplay: function(reason /* String */){ /* void */ // summary: Halts replaying this command log. // reason: String // The reason we halted. // description: // This method is called as we are replaying an action log; it // can be called from dojox.off.sync.actions.onReplay, for // example, for an application to indicate an error occurred // while replaying this action, halting further processing of // the action log. Note that any action log entries that // were processed before have their effects retained (i.e. // they are not rolled back), while the action entry that was // halted stays in our list of actions to later be replayed. if(!this.isReplaying){ return; } if(reason){ this.reasonHalted = reason.toString(); } // save the state of our action log, then // tell anyone who is interested that we are // done when we are finished saving if(this.autoSave){ var self = this; this._save(function(){ self.isReplaying = false; self.onReplayFinished(); }); }else{ this.isReplaying = false; this.onReplayFinished(); } }, continueReplay: function(){ /* void */ // summary: // Indicates that we should continue processing out list of // actions. // description: // This method is called by applications that have overridden // dojox.off.sync.actions.onReplay() to continue replaying our // action log after the application has finished handling the // current action. if(!this.isReplaying){ return; } // shift off the old action we just ran this.entries.shift(); // are we done? if(!this.entries.length){ // save the state of our action log, then // tell anyone who is interested that we are // done when we are finished saving if(this.autoSave){ var self = this; this._save(function(){ self.isReplaying = false; self.onReplayFinished(); }); return; }else{ this.isReplaying = false; this.onReplayFinished(); return; } } // get the next action var nextAction = this.entries[0]; this.onReplay(nextAction, this); }, clear: function(){ /* void */ // summary: // Completely clears this action log of its entries if(this.isReplaying){ return; } this.entries = []; // save our updated state into persistent // storage if(this.autoSave){ this._save(); } }, replay: function(){ /* void */ // summary: // For advanced usage; most developers can ignore this. // Replays all of the commands that have been // cached in this command log when we go back online; // onCommand will be called for each command we have if(this.isReplaying){ return; } this.reasonHalted = null; if(!this.entries.length){ this.onReplayFinished(); return; } this.isReplaying = true; var nextAction = this.entries[0]; this.onReplay(nextAction, this); }, // onReplayFinished: Function // For advanced usage; most developers can ignore this. // Called when we are finished replaying our commands; // called if we have successfully exhausted all of our // commands, or if an error occurred during replaying. // The default implementation simply continues the // synchronization process. Connect to this to register // for the event: // // dojo.connect(dojox.off.sync.actions, "onReplayFinished", // someFunc) onReplayFinished: function(){ }, toString: function(){ var results = ""; results += "["; for(var i = 0; i < this.entries.length; i++){ results += "{"; for(var j in this.entries[i]){ results += j + ": \"" + this.entries[i][j] + "\""; results += ", "; } results += "}, "; } results += "]"; return results; }, _save: function(callback){ if(!callback){ callback = function(){}; } try{ var self = this; var resultsHandler = function(status, key, message){ //console.debug("resultsHandler, status="+status+", key="+key+", message="+message); if(status == dojox.storage.FAILED){ dojox.off.onFrameworkEvent("save", {status: dojox.storage.FAILED, isCoreSave: true, key: key, value: message, namespace: dojox.off.STORAGE_NAMESPACE}); callback(); }else if(status == dojox.storage.SUCCESS){ callback(); } }; dojox.storage.put("actionlog", this.entries, resultsHandler, dojox.off.STORAGE_NAMESPACE); }catch(exp){ console.debug("dojox.off.sync._save: " + exp.message||exp); dojox.off.onFrameworkEvent("save", {status: dojox.storage.FAILED, isCoreSave: true, key: "actionlog", value: this.entries, namespace: dojox.off.STORAGE_NAMESPACE}); callback(); } }, _load: function(callback){ var entries = dojox.storage.get("actionlog", dojox.off.STORAGE_NAMESPACE); if(!entries){ entries = []; } this.entries = entries; callback(); } });dojox.off.sync.actions = new dojox.off.sync.ActionLog();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -