logo资料库

Web表现层分离表现与数据方法的探讨.pdf

第1页 / 共3页
第2页 / 共3页
第3页 / 共3页
资料共3页,全文预览结束
本栏目责任编辑: 闻翔军 数据库及信息管理 在 Web 表现层分离表现与数据方法的探讨 ( 武汉理工大学 计算机科学与技术学院, 湖北 武汉 430080) 高凌 1, 熊前兴 2 摘要: 本文简要介绍了 XMLHttpR equest 对象, 随后详细阐明了如何在 web 应用中利 用 XMLHttpR equest 结 合 XML 在 表 现 层 实 现 表现与数据的分离的方法。并在文章结尾阐述了该方法在 web 应用中的广泛前景。 关键词: XMLHttpR equest 对象; Ajax; 数据分离 中图分类号: TP393.02 文献标识码: A 文章编号: 1009- 3044(2007)02- 10301- 02 Res earch on the Pres entation and Data Separating in the Web Pres entation Layer GAO Ling1,XIONG Qian- Xing2 (Wuhan University of Technology,Wuhan 430080,China) Abs tract:This paper introduce the XMLHttpR equest Object and illustrate how to separate Presentation and Data in the presentation layer of a web application with the XMLHttpR equest and XML. Key words :XMLHttpR equest Object;Ajax;Separate data 1 引言 在 web 应用的发展过程中, Model2(MVC)架构的 出 现, 分 离 了 model1 中 混 杂 的 业 务 逻 辑 与 表 现 , 但 有 一 个 问 题 始 终 困 扰 着 我 们, 即表现层中的表现与数据仍混杂在一起。例如: 在传统 web 开 发 中 , 使 用 来描述一个 html text 控 件 。 其 中, value=”321”表 示 该 控 件 的值, class="input"描述了该控件在浏览器中显示的外观。这样的 传 统 方 法 虽 然 简 单 一 目 了 然 , 但 它 的 缺 点 也 是 显 而 易 见 的 : 表 现 与 数 据 值 混 杂 , 一 旦 这 样 的 值 要 被 服 务 器 传 递 的 另 一 个 值 所 替 代, 页面就要被刷新。本文探讨了一种新的模式, 使得 html 控件与 数据分离, 控件与数据的绑定工作交给浏览器完成。 2 XMLHttpReques t 对象概述 XmlHttp 是 一 套 可 以 在 Javascript、VbScript、Jscript 等 脚 本 语 言 中 通 过 http 协 议 传 送 或 从 接 收 XML 及 其 他 数 据 的 API[1]。 XmlHttp 最大的用处是可以更新网页的部分内容而不需要刷新整 个页面。 现在的绝对多数浏览器都增加了对 XmlHttp 的支持, IE 中 使 用 ActiveXObject 方 式 创 建 XmlHttp 对 象, 其 他 浏 览 器 如 : Firefox、 Opera 等通过 window.XMLHttpRequest 来创建 xmlhttp 对象。在使 用 XMLHttpRequest 对 象 发 送 请 求 和 处 理 响 应 之 前 , 必 须 先 用 javascript 创 建 一 个 XMLHttpRequest 对 象 , 由 于 XMLHttpRequest 不 是 一 个 W3C 标 准 , 所 以 要 采 用 多 种 方 法 来 创 建 XMLHttpRe- quest 的实例。代码如下: var xmlHttp; //创建 XMLHttpRequest 对象 function createXMLHttpRequest(){ /* 为保证浏览器兼容性, 做如下处理。 如 果 浏 览 器 支 持 ActiveX 对 象 , 则 用 ActiveX 来 创 建 XML- HttpRequest 对象, 否则使用本地 JavaScript 对象技术来创建 */ if(window.ActiveXObject){ xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } else if(window.XMLHttpRequest){ xmlHttp=new XMLHttpRequest(); } } 从上面代码可以看出, 在 IE 中把 XMLHttpRequest 实现为一 个 ActiveX 对象, 其它浏览器把它作为一个本地 JavaScript 对象。 3 表现与数据分离方法的探讨 3.1 表现与数据分离的方法 本文对 web 应用的表现层进行了分析, 将表 现 层 拆 分 为 html 页面模块、数据模块、javascript 客户端模块三个模块。 ( 1) html 页面模块。 该模块由 html 控件及其他诸如 css 等组成。对于 web 程序开 发人员, 更关心数据的承载部分以及少量的页 面 修 饰 。 而 网 页 的 数据承载, 是通过 html 控件的形式表现的。如 ,,表单等等。将这类控件以不带值得形 式表现出来, 就构成了 html 页面模块。例如: ( 2) 数据: 通常由服务器 从 数 据 库 中 读 取 。 以 XML 为 最 终 表 现 形式。因此, 可以通过一个 java servlet 来取得数据库中的值, 然 后将其格式化为标准的 xml 输出。 ( 3) javascript 客户端: 用于绑定 html 控 件( 或 称 为 html 对 象) 和数据。上面已经得到了 html 控件和数据,接 下 来 最 关 键 的 问 题 是 如 何 让 数 据 显 示 在 正 确 的 位 置 。 这 需 要 用 到 XMLHttpRequest 对 象 。 首 先 , 声 明 一 个 XMLHttpRequest 对 象 xmlHttp=new Ac- tiveXObject("Microsoft.XMLHTTP")。随后, 建立对模块②中生成的 数据的调用: xmlHttp.open("Get",url,true)。最后, 取得这样的服务器 数据并与 html 控件绑定。 Html 控 件 值 = xmlHttp.responseXML.getElementsByTagName (“数据库字段名”) document.getElementById ("html 控 件 ID").innerHTML= Html 控件值 收稿日期: 2006- 10- 02 基金项目: 湖北省交通厅水路规费外网建设项目 作者简介: 高凌( 1982- ) , 男, 湖北浠水人, 武汉理工大学科学与技术学院硕士研究生, 研究方向为计算机支撑技术; 熊前兴( 1943- ) , 男, 博导, 研究方向为计算机支撑技术, 电子商务, Web 数据集成等。 301
数据库及信息管理 本栏目责任编辑: 闻翔军 经过上述的三个拆分, 我们用在 Web 表现层分离表现与数据 的思想实现了一个传统的 web 页面编程的工作( 流程见图 1) 。 称,全年通航里程,季节通航里程,不通航里程,总计里程,航道属性,船 闸数量,升船机数量,其它建筑物数量,总计建筑物数量 等对象 Varid,name,jumpingOffPoint,endPoint,aOnTraffic,sOnTraffic, nOnTraffic,sumOnTraffic, seaRouteAttribute,gate,osMachine,otherBuilding,sumBuilding; 取 值 的 第 二 步 是 对 上 面 定 义 的 js 变 量 赋 值 。 我 们 使 用 xml- Http 取出 xml 中的数据。然后把该数据赋值给 js 变量。 id=xmlHttp.responseXML.getElementsByTagName (" 序 号")[0]. firstChild.nodeValue; name =xmlHttp.responseXML.getElementsByTagName (" 航 道 名 图 1 称")[0].firstChild.nodeValue; 模块①可分离出来单独由 html 页面编写人员处理, web 程 序 员 只 关 心 业 务 逻 辑 , 关 心 数 据 如 何 从 数 据 库 到 模 型 层 , 再 到 业 务 层, 最后变成规范的 XML 格式。 3.2 表现与数据分离方法的具体实现 下面以湖北港航电子政务系统- - - 航道模块为例, 从数据库 中的航道明细表中得到: 航道名称、航道起点等信息。并由此计算 出航道里程总计和通航建筑物数量总计。其中, 航道里程总计=全 年通航航道里程+季节通航航道里程+不通航航道里程; 通航建筑 物数量总计=通航船闸数量+通航升船机数量+其它通航数量; <湖北省航道情况表> <序号>1 <航道名称>长江 <航道起点>段窑断面 <航道终点>鳊鱼溪 <全年通航航道里程>1037.90 <季节通航航道里程>10 <不通航航道里程>0 <航道里程总计>1047.90 <航道属性>天然 <通航船闸数量>3 <通航升船机数量>1 <其它通航数量>1 <通航建筑物数量总计>5 服务器端生成如上所示的 XML 文件后送给浏览器。 同时, 在浏览器端, 我们得到 html 页面 序号: 名称: 航道 起 点: 此 时 , 页 面 与 数 据 都 具 备 了 , 下 一 步 工 作 是 如 何 使 用 javascript 绑定值与对象。 首先是取值: 从经过业务逻辑处 理 得 到 的 XML 文 件 中 将 值 解析出来, 赋给 javascript 变量。 取值的第一步, 创建序号,航道名称,航道起点名称,航道终点名 302 电脑知识技术 jumpingOffPoint =xmlHttp.responseXML.getElementsByTagName ("航道起点")[0].firstChild .nodeValue; endPoint=xmlHttp.responseXML.getElementsByTagName(" 航 道 终点")[0].firstChild.nodeValue; aOnTraffic=xmlHttp.responseXML.getElementsByTagName (" 全 年通航航道里程")[0].firstChild .nodeValue; sOnTraffic=xmlHttp.responseXML.getElementsByTagName (" 季 节通航航道里程")[0].firstChild .nodeValue; nOnTraffic=xmlHttp.responseXML.getElementsByTagName (" 不 通航航道里程")[0].firstChild .nodeValue; sumOnTraffic =xmlHttp.responseXML.getElementsByTagName (" 航道里程总计")[0].firstChild .nodeValue; seaRouteAttribute =xmlHttp.responseXML.getElementsByTag- Name("航道属性")[0].firstChild .nodeValue; gate=xmlHttp.responseXML.getElementsByTagName(" 通 航 船 闸 数量")[0].firstChild.nodeValue; osMachine=xmlHttp.responseXML.getElementsByTagName (" 通 航升船机数量")[0].firstChild .nodeValue; otherBuilding =xmlHttp.responseXML.getElementsByTagName (" 其它通航数量")[0].firstChild .nodeValue; sumBuilding =xmlHttp.responseXML.getElementsByTagName (" 通航建筑物数量总计")[0] .firstChild.nodeValue; 取 值 的 工 作 完 成 后, 接 下 来 是 对 html 表 单 控 件 赋 值 : 将 上 述 得到的值与 Html 控件进行绑定。 document.getElementById("id").innerHTML=id; document.getElementById("name").innerHTML=name; document.getElementById ("jumpingOffPoint").setAttribute("val- ue",jumpingOffPoint); document.getElementById ("endPoint").setAttribute ("value",end- Point); document.getElementById ("aOnTraffic").setAttribute ("value", aOnTraffic); document.getElementById ("sOnTraffic").setAttribute ("value", sOnTraffic); document.getElementById ("nOnTraffic").setAttribute ("value", nOnTraffic); document.getElementById ("sumOnTraffic").setAttribute ("value", sumOnTraffic); document.getElementById ("seaRouteAttribute").innerHTML = seaRouteAttribute; (下转第 309 页)
本栏目责任编辑: 闻翔军 IF len(alltrim(thisform.text1.value))! =0 tiaojian=tiaojian+".and."+"dzbh="+" ' value)+"' " ENDIF IF len(alltrim(thisform.text2.value))! =0 tiaojian=tiaojian+".and." +"xm=" +" ' value)+"' " ENDIF IF len(alltrim(thisform.text3.value))! =0 tiaojian=tiaojian+".and."+"szdw="+" ' "+alltrim(thisform.text1. " +alltrim(thisform.text2. "+alltrim(thisform.text3. value)+"' " ENDIF thisform.dataenvironment.cursor1.filter=tiaojian thisform.refresh 5.2.2 程序代码说明 单 选 按 钮 组 的 Name 属 性 为 默 认 值 Optiongroup1 ( 参 见 2.2 节 ) , 在 程 序 中 , 若 thisform.optiongroup1.value=1, 则 表 明 选 中 了 单 选按钮组中的第一个单选按钮, 即选中“全部”。同理, thisform.op- tiongroup1.value=2 表明选中第二个单选按钮 “学生”, thisform.op- tiongroup1.value=3 表明选中第三个单选按钮“非学生”。 组合框的 Name 属性为默 认 值 Combo1( 参 见 2.2 节) , 在 程 序 中, 若 thisform.combo1.listindex=1, 则 表 明 选 中 了 组 合 框 的 下 拉 列 表 中 的 第 一 个 列 表 项 , 即 选 中 “ 不 限 ”。 同 理 , thisform.combo1. listindex=2 表明选中组合框的下拉列表中的第二个列表项 “男”, thisform.combo1.listindex=3 表 明 选 中 组 合 框 的 下 拉 列 表 中 的 第 三 个列表项“女”。 读者编号、姓名、所在单位对应的文本框的 Name 属性分别为 Text1、Text2、Text3( 参 见 2.2 节) 。 要 判 断 这 些 文 本 框 是 否 有 希 望 输入的数据, 可先提取这些文本框的内容, 再去掉前后空格, 然 后 再检查剩余部分的长度是否为 0。长度为 0 表示文本框中的内容 是空字符串或无输入内容, 长度不为 0 表示有希望的数 据 输 入 。 在程序中, 提取 Text1 文本框的内容用 thisform.text1.value, 去掉前 后 空 格 用 alltrim()函 数 , 计 算 字 符 串 长 度 用 len()函 数 , 这 样 , len (alltrim(thisform.text1.value))! =0 表 示 读 者 编 号 对 应 的 文 本 框 ( 即 text1 文 本 框 ) 有 希 望 输 入 的 数 据 。 同 理 , len(alltrim(thisform.text2. value))! =0、len(alltrim(thisform.text3.value))! =0 分别表示姓名、所在 单位文本框有希望输入的数据。 程 序 及 查 询 流 程 图 ( 参 见 图 2) 中 的 sfxs、xb、xm、szdw 分 别 对 (上接第 302 页) document.getElementById("gate").setAttribute("value",gate); document.getElementById ("osMachine").setAttribute ("value",os- Machine); document.getElementById ("otherBuilding").setAttribute ("value", otherBuilding); document.getElementById ("sumBuilding").setAttribute("value", sumBuilding); 演示结果 数据库及信息管理 应于 duzhe.dbf 数据表中的字段名, 其含义分别为是否学生、性别、 姓名、所在单位( 参见表 1) 。另外, 程序中的 tiaojian 表示设定的内 存变量, 表示查询条件。 程 序 中 thisform.dataenvironment.cursor1.filter=tiaojian 用 于 将 数 据 环 境 中 对 应 于 数 据 表 duzhe.dbf 的 游 标 cursor1 的 Filter 属 性 设置为 tiaojian, 而 thisform.refresh 用于刷新表单。 5.3 退出查询 如 前 所 述 , 表 单 运 行 后 , 若 单 击“退 出 ”按 钮 , 则 释 放 表 单 , 退 出查询功能模块。所以, 可以在“退出”命令按钮控件的 Click 事件 中添加如下 VFP 程序代码: thisform.release。 6 进一步说明 (1) 选项按钮组或组合框对象都可以用于有限可选 项 的 单 项 选择。对于查询范围及性别的选择, 由于它们都具有 有 限 的 可 选 项, 并 且 各 自 的 可 选 项 都 是 相 互 排 斥 的 , 所 以 都 可 以 在 设 计 时 利 用选项按钮组对象的控件或组合框对象的控件来实现。本文为阐 明 这 两 种 控 件 的 用 法 , 分 别 使 用 了 选 项 按 钮 组 控 件 和 组 合 框 控 件。 (2)若进行精确查询, 则需要进行精确比较。这时可在 表 单 的 Load 事件中添加代码: set exact on, 并在表单的 Unload 事件中添 加代码: set exact off。 (3) 有时单击文本框对象时, 希望将文本框中原有 的 内 容 清 除, 以方便使用。这时可以在文本框控件的单击事件 中 将 此 文 本 框的 value 属性设置为空白字符串。例如, 运行查询表单过程中, 单击 Text1、Text2 及 Text3 文本框时, 希望将上次操作输入的内容 清 除 , 从 而 可 以 直 接 输 入 新 值 , 为 达 此 目 的 , 可 以 分 别 在 Text1、 Text2、Text3 文本框控件的 Click 事件中添加 如 下 代 码: this.value= space(0)。 (4)有时希望鼠标移到某对象上时能够显示提示文字, 就 需 要 分 别 设 置 表 单 的 ShowTips 属 性 和 此 对 象 控 件 的 ToolTipText 属 性 。 例 如, 可 以 将 表 单 的 ShowTips 属 性 设 置 为“.T.- 真 ”, 将 Text1 文本框控件的 ToolTipText 属性值设置为“此文本框为空白值或无 输 入 数 据 时, 表 示 查 询 时 不 对 读 者 编 号 做 任 何 限 制 ”, 将 Text2 文 本框控件的 ToolTipText 属性值设置为“此文本框为空白值或无输 入 数 据 时, 表 示 查 询 时 不 对 姓 名 做 任 何 限 制 ”, 将 Text3 文 本 框 控 件的 ToolTipText 属性值设置为“此文本框为空白值或无输入数据 时, 表示查询时不对所在单位做任何限制”。 4 结束语 通 过 以 上 工 作 , 在 web 表 现 层 分 离 了 表 现 与 数 据 , 降 低 了 html 对象与数据的强耦合, 使得网页设计人员与程 序 员 的 分 工 界 线更加明确。网页开发人员只用关注 html 页面的设计, 程序员只 关心从数据取出到生成 XML 的业务逻辑过程。数据与 html 控件 的绑定是有规律可循的, 可以被提取为通用的 JS 组件。 参考文献: [1]Ryan Asleon,Nathaniel T.Schutta.Foundations of Ajax.ISBN: 7- 115- 14481- 8,人民邮电出版社.2006( 2) . [2]Gay S.Horstmann,Gary Cornell 著 , 程 峰 , 黄 若 波 译.java2 核 心 技 术, java2 高 级 特 性.ISBN: 7- 111- 12543- 6. 机 械 工 业 出 版 社. 2004( 6) . [3]Dave Crane,Eric Pascarello, Darren James 著.Ajax in Action. ISBN: 1- 932394- 61- 3.2006( 4) . [4]李刚, 宋伟, 邱哲.Ajax+Lucene 构建搜索引擎.ISBN: 7- 115- 14707- 8.人民邮电出版社.2006( 4) . 309
分享到:
收藏