使用dojo离线功能2-开发

4.   开发 Dojo 离线应用程序

一般来说开发一个离线应用有以下几个步骤:

l         应用加载时缓存所引用的资源

l         应用加载之后设置必要的离线事件处理函数。如:与服务器进行同步操作时的下载和完成下载事件,重放事件等。

l         检查应用是否在线,读取应用所需的数据。如果离线则从本地读取数据;如果在线则与服务器数据进行同步,首先上传离线数据(如果有的话),然后从服务器上下载最新数据。

l         初始化应用程序。

4.1. 保存离线资源

为了使页面能够在离线情况下操作,在页面加载时必须要保存页面所引用的 JavaScript 文件, CSS 文件,图片文件等资源,这样在与服务器断开连接时,页面便能够从本地缓存中提取到页面相关的数据和资源。 Dojo 提供了一个功能非常强大的函数 slurp 来实现这一功能。 slurp 函数在页面加载之后会自动分析页面所引用的资源,并得到一个资源文件的 url 列表,然后抓取 url 的内容,保存到 Google Gears 中。 slurp 函数能够缓存大部分的资源文件,包括引用 CSS 文件里的图片,但是使用内联方式指定的 CSS 图片以及用 JavaScript 动态产生的引用 slurp 则无法进行缓存。这种情况可以通过调用 dojox.off.files.cache () 来手动添加要缓存的资源,具体用法详见后文。

Dojo Offline 还提供了在调试时查看已缓存资源文件的方法,首先以 debug 方式加载 Dojo ,然后在页面和 Dojo Offline 加载完之后调用 dojox.off.files.printURLs() 函数。这个函数会在控制台以调试的方式打印出已缓存的资源文件 url

4.2. 保存和使用离线数据

一般来说,离线应用不仅要缓存页面所引用的 JavaScript CSS ,图片等资源,还要缓存页面所使用的数据。 Dojo Google Gears 的访问接口进行了封装,提供了 Dojo Storage Dojo SQL 两种方式操作离线数据。通过这两种方式,用户可以方便、灵活地保存和读取离线数据。

l         Dojo Storage

提供了一种类似哈希表的方式对数据进行操作,数据以键值对的方式存取。

保存: dojox.storage.put(key,value) — key 是字符串类型, value 可以是字符串和可序列化的 JavaScript 对象,但是浏览器对象(如 DOM 节点和 XMLHttpRequest 对象)是不能够保存的。

读取: var value = dojox.storage.get(key) — 获取字符串 key 对应的值。

var car = {type: "Nissan", color: "white", price: 20000, optional: "air-conditioner, stereo"};

dojox.storage.put("complexKey", car);

 

var value = dojox.storage.get("someKey");

var car = dojox.storage.get("complexKey");

if(car)

alert(car.type);

上述代码先将一个对象 car 放置在 Dojox.Storage 里,然后又从中取出并展示。

l         Dojo SQL

通过 Dojo SQL Google Gears 关系存储层的封装,能够以更适合 JavaScript 对象的访问方式对关系表进行操作。如下所示,我们对 Documents 表进行了创建,插入,查询操作:

//create Documents table if not exist

dojox.sql("CREATE TABLE IF NOT EXISTS DOCUMENTS ("

                     + "fileName           TEXT NOT NULL PRIMARY KEY UNIQUE, "

                     + "content             TEXT NOT NULL) ");

//insert a record

dojox.sql("INSERT INTO DOCUMENTS (fileName, content) VALUES (?, ?)", fileName, contents);

//query

var results = dojox.sql("SELECT * FROM DOCUMENTS WHERE fileName = ?", someFileName);

Dojo 查询操作返回的是一个记录对象的数组,如访问第一条记录的 fileName 字段,可以使用 results[0].fileName ,访问 content 字段则可以使用 results[0].content

4.3. 与服务器同步数据

离线操作产生的新数据,在与服务器连接可用时需要上传到服务器;并且,在该用户离线期间,其他用户也可能已经更改过数据,因此重新连接服务器时需要下载最新的数据。 Dojo 的同步操作发生的时机,位于页面首次加载并且在线的时候,或是离线后又检测到连接恢复的时候,具体包括 3 个步骤:

1.         下载并缓存最新的页面资源,包括由 slurp 函数以及用户手动缓存的资源。离线 UI 控件, Dojo Offline Widget ,会自动更新相应的状态,如下图所示:

2.         上传用户在离线期间所创建的数据。

3.         下载服务器最新数据进行展示。

如上所示, Dojo Offline 提供了一个 UI 控件来通知用户当前的状态,如下载,上传,网络连接状态等。 Dojo Offline Widget 处理了大部分的逻辑,开发人员可以直接在页面中使用该控件。使用 Offline Widget 很简单,只需在页面加入一个占位符即可。 Offline Widget 也提供了扩展机制,以更改图片和样式等来跟页面风格保持一致。

4.4. Dojo 离线应用示例

Dojo Offline 随附的开发包中提供了 3 个例子,下面以 hello world 为例说明如何构建一个简单的离线应用。 hello world 程序模拟了用户与服务器简 单的消息交互。用户界面包括一个输入框和一个发送按钮,在输入框里输入文本,点击发送按钮将消息发送到服务器。为了保持用例的简单,实际上消息并没有真正 被发送到服务器,而只是简单地将其弹出。在应用离线时,点击发送按钮则会在本地保存离线操作的数据,当应用重新连接时则会重新执行该操作。

1.         首先加载 Dojo 及离线所使用的 JavaScript 文件。

       <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>

       <script type="text/javascript" src="../../../../dojox/off/offline.js"></script>

当然,我们也可以用 dojo.require 方法进行加载。

       <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>

       <script type="text/javascript" >

        dojo.require(“dojox.off.offline”);

</script>

2.         设置应用程序名字,这个名字会显示在 Dojo Offline Widget 上。

       dojox.off.ui.appName = "Hello World";

3.         缓存页面资源文件。要使离线功能正常工作,这个函数必须在 Dojo Offline 初始化之前调用,即 dojox.off.initialize 函数调用之前。

       dojox.off.files.slurp();

4.         初始化应用程序,设置离线操作的一些事件响应函数。

initialize: function(){

       console.debug("helloWorld.initialize");              

       var self = this;

       dojo.connect(dojox.off.sync, "onSync", this, function(type){

              if(type == "download"){

                     self._messages.push("Hi! This is fake downloaded data!");        

                     dojox.storage.put("messages", self._messages);

                     dojox.off.sync.finishedDownloading();

              }else if(type == "finished"){                            

                     this._messages = [];

                     dojox.storage.remove("messages");

              }

       });  

       dojo.connect(dojox.off.sync.actions, "onReplay", this,

                            function(action, actionLog){

                                   if(action.name == "new hello world message"){

                                          var message = action.data;

                                          self.sendMessage(message);

                                          actionLog.continueReplay();

                                   }

       });

       if(!dojox.off.isOnline){

              this.loadOfflineData();

       }

       this.printMessages();

}

可以看到,此处最主要的两个操作是设置 dojox.off.sync onSync 事件和 dojox.off.sync.actions onReplay 事件。其中, onSync 用来处理与服务器的同步, download 事件发生在第一次加载页面或是网络重新连接的时候,在该事件中我们应该从服务器下载数据,并在下载完毕之后记得调用 dojox.off.sync.finishedDownloading() ,以便告诉 Dojo Offline Widget 更新当前状态。 finished 事件则说明从服务器下载数据结束,可以更新应用程序了。

Dojo Offline 使用 action log 来记录用户在离线时的操作,并在重新获得网络连接时重新执行这些操作,将数据上传到服务器。

一般来说,程序初始化时首先要判断应用是否在线,如果不在线则加载本地数据进行页面展示。值得注意的是,这些事件何时触发都是由 Dojo Offline 的同步框架自动进行处理的,开发人员只需设置相应的事件处理函数即可。

5.         保存离线数据,这是通过创建 action log 来实现的。在与服务器重新连接时 action log 会自动重新执行。

saveOfflineSend: function(message){  

       this._messages.push(message);

       dojox.storage.put("messages", this._messages);                               

       var action = {name: "new hello world message", data: message};

       dojox.off.sync.actions.add(action);                                  

       alert("This message has been saved for sending when we go back online");

}

6.         Dojo 的离线功能要在页面加载完及 Dojo Offline 初始化之后才能工作,因此页面本身的代码要在 Dojo Offline 初始化完成之后执行。 Dojo Offline 的初始化完成可以用 dojox.off.ui onLoad 事件来标识。我们首先将页面的初始化函数绑定到 dojox.off.ui onLoad 事件,然后调用 dojox.off.initialize 函数对 Dojo Offline 进行初始化。

       dojo.connect(dojox.off.ui, "onLoad", helloWorld, "initialize");

dojox.off.initialize();

7.         加载 Dojo Offline Widget 。实际上任何 html 元素,只要 id 为“ dot-widget ”都可以作为 Offline Widget 的占位符。 Dojo Offline 初始化的时候会对这个元素进行填充。

       <div id="dot-widget"></div>      

8.         为页面加入展示元素。

              <div id="helloMessage" style="margin: 1em;">

                     <label for="helloInput"        style="margin-right: 0.2em;">

                            Enter Hello World Message:

                     </label>               

                     <input name="helloInput" id="helloInput" style="margin-right: 0.2em;">

                     <button id="sendMessage" οnclick="helloWorld.send()"

                                   style="margin-right: 0.2em;">Send</button>

              </div>                  

              <p>Debug output:</p>

9.         运行 hello world

hello world 示例程序不涉及服务器端代码,因此并不需要部署才能执行。但是为了便于测试在线 / 离线操作,建议最好还是通过服务器访问。

Dojo Offline 里随附的例子中, Moxie 编辑器是一个包括服务器和客户端的完整应用程序,它使用 Jetty 作为 Web 容器,使用 Derby 作为数据库。我们可以启动 Moxie 应用所在的 Jetty 容器来访问 hello world 应用。

首先请安装 jdk1.5 或以上版本,在 dojox/off/demos/editor/server/ 目录下,运行:

java -jar editor.jar

在浏览器地址栏输入 http://localhost:8000/dojox/off/demos/helloworld/helloworld.html 即可访问 hello world 应用。可以通过关闭 / 打开 Jetty 来观察 hello world Dojo Offline Widget 在离线、在线及同步时的行为。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值