`
wangangie40
  • 浏览: 5282 次
  • 性别: Icon_minigender_2
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

实战 OpenLaszlo 与 db4o

 
阅读更多

  本文于去年年底完成,由于篇幅原因,裁减后提交到《程序员》杂志社,并于2007年2月出版在《程序员》杂志上,文章改名为《开源RIA架构方案-Openlaszlo与db4o》。时隔半年,我把完整的文章提交上来,希望对想要了解 Openlaszlo 的开发者提供帮助。另外,发表在本 blog 上的这篇文章版权归《程序员》杂志社所有。
  前言 
  RIA ( Rich Internet Applications ),这个术语已经出现多年,随着开源社区和厂商的不断贡献,涌现出许多 RIA 产品,几个重要产品分别是: 
  Adobe Flex -- 基于 Flash 、 actionscript 、 MXML 。 
  OpenLaszlo -- 基于 Flash 、 JavaScript 、 LZX 。 
  Dojo -- 基于 JavaScript 、 DHTML 、 XML 。 
  XUL -- 基于 XUL 、 JavaScript 。 
  除了以上产品外,还有大量的 Ajax 、 Applet 开源项目。他们的目的只有一个:简化并改善 Web 应用程序的交互操作,使应用程序可以提供更丰富、更具有交互性和响应性的用户体验。 
  本文 UI 方面,我们关注重点是 OpenLaszlo 。 OpenLaszlo 的前身是 LPS ( Laszlo Presentation Server ),由 Laszlo Systems 公司在 2002 年发布, LPS 是那个时代诞生的第一个 RIA 产品。根据市场和用户的需要, Laszlo Systems 公司于 2004 年在 CPL 协议下发布了 LPS 的开源产品 OpenLaszlo 。目前,代号为" Legals "的 OpenLaszlo 即将在明年第一季度发布,它的出现使 OpenLaszlo 能够支持 Ajax ( DHTML )。 " Legals "的下一个项目代号为" Osprey ",它的目标是支持 swf9 的运行目标,也就是当前 Flex 2 所采用的运行文件版本,预计发布时间为明年的第二或者第三季度。 代号为 " Orbit " 的项目是 Sun 和 Laszlo Systems 公司共同开发的产品, 目的是能让 OpenLaszlo 程序运行在包括 Java ME 在内的任何 Java 平台上, 比如移动电话、 PDA 、电视机顶盒、打印机, 等等。 
  OpenLaszlo 优势在于它是开源的( 遵循 CPL 协议 ), 基于开发者熟悉的技术( JavaScript 、 XML ) 。在 SOLO ( Standalone OpenLaszlo Output )方式下可部署到任意的 HTTP Web 服务器,在非 SOLO 方式( Proxied 方式)下可部署在装有 OpenLaszlo Server 的 Linux 、 UNIX 、 Windows 、 Mac OS X 操作系统上,并支持任意的 Java Servlet 容器、 Java EE 应用服务器。只要您的浏览器支持 Flash 6 或者更高版本,那么就可以体验 OpenLaszlo 了。 
  本文利用 db4o 作为数据库, db4o 是一个开源的纯面向对象数据库引擎,对于 Java 与 .NET 开发者来说都是一个简单易用的对象持久化工具。同时, db4o 已经被众多的企业级应用验证为具有优秀性能的面向对象数据库。可以通过《 开源面向对象数据库 db4o 之旅: 初识 db4o 》、《 开源面向对象数据库 db4o 之旅: db4o 查询方式 》系列文章来了解。 
  OpenLaszlo 安装 
  以 Windows 2000/XP 安装为例,首先安装 Java 1.4 或以上版本,接着下载 OpenLaszlo Server 3.3.3 ,这个过程并不困难,安装完毕会自动进入 OpenLaszlo 欢迎页面,很漂亮的世界时钟。 
  现在就可以立即体验 OpenLaszlo 的魅力了,只要您有任何一款 XML 编辑器就行,哪怕是 Windows 自带的记事本。转到 OpenLaszlo 的默认安装目录"C:\Program Files\OpenLaszlo Server 3.3.3\Server\lps-3.3.3",新建文件夹"hello",然后在"hello"文件夹下新建"hello.lzx"文件,向其中写入: 
  < canvas width ="200" > 
  < text > Hello World! </ text > 
  </ canvas > 
  第一个程序完成。 
  "效果很不错 …… ",也许您还在欣赏自己地杰作,不过马上感到这样开发不太方便,好在 OpenLaszlo 为我们提供了 Eclipse 插件 IDE4Laszlo , IDE4Laszlo 以前是 IBM alphaWorks 项目,现在已经开源给 Eclipse ,可在 这里 找到,目前的版本是 0.2.0 。安装插件之前还必须确保您的 Eclipse 安装了 WTP1.0 SDK 。 
  接下来安装插件,在 Eclipse 的菜单栏选择" Select Help >> Software Updates >> Find and Install "再选中" Search for new features to install ",点击" New Archived Site "按钮选择刚才下载的插件 zip 文件,最后根据提示即可顺利完成插件安装。 
  上面的 OpenLaszlo Server 依靠 Tomcat 服务器为运行环境,不过 OpenLaszlo 也可以运行在例如 Jboss 、 WebLogic 、 WebSphere 等服务器中,并构建自己的运行环境。本应用程序是在 OpenLaszlo 自己的运行环境中构建,可以在 这里 下载。 
  程序架构 
  与传统 Web 应用一样,RIA 应用也遵循 MVC 模式,只不过客户端要依赖控制端和服务端提供数据来更新视图,所以多了一个数据层。本实例为了简化程序,使用 JSP 文件来作为控制层与数据层的桥梁,当用户进行操作请求时,OpenLaszlo 向 JSP 发出请求,JSP 获得请求并分析应该调用哪种业务操作,业务层根据所请求的方法与持久层进行交互,将获取的数据以 XML 字符串的形式返回,并通过 JSP 页面传递给 OpenLaszlo 应用。 
  下面在 Eclipse 建立一个 Laszlo 工程以展示这个应用的程序结构(由于该应用程序是基于独立的 OpenLaszlo 运行环境,所以未使用 IDE4Laszlo 提供的特性)。 
  打开 Eclipse,创建一个名为"openlaszloWITHdb4o"的 Web 应用程序。接着转入该程序的所在目录,为了能保证该应用程序能顺利加入 RIA 特性进行如下操作:
  1、从 OpenLaszlo 独立运行环境的 war 包中拷贝"openlaszlo-3.3.3-servlet\lps"目录到"openlaszloWITHdb4o\"下,该目录是 OpenLaszlo 的组件库。 
  2、 复制"openlaszlo-3.3.3-servlet\WEB-INF\lib"目录到"openlaszloWITHdb4o\WEB-INF\",该目录是 OpenLaszlo 的支持库,然后在该项目的"Java Build Path"中引入这些库,同时再引入 dom4j 和 db4o 的支持库,应用程序的服务器端会用到。 
  3、 复制"openlaszlo-3.3.3-servlet\WEB-INF\lps"目录到"openlaszloWITHdb4o\WEB-INF\",该目录是 OpenLaszlo 的组件配置信息。 
  4、在"openlaszloWITHdb4o\src"下,分别创建 bo、com 包和类文件,接着创建"helloDb4oUser.lzx"和"peopleoperat.jsp"文件。 
  5、 最后,把 war 包的 web.xml 文件拷贝过来,启动 OpenLaszlo Server 引擎全靠它了。 
  服务器端代码 
  应用程序使用了 Java 5 特性,请保证您的开发环境与本文一致。bo 包是整个用户管理应用程序的数据模型,People 类定义了"用户",包含姓名、电话等基本信息,请 下载程序源码查看。 
  com 包是与持久层交互的重要部分,Db4oInit 类是一个 Servlet,它的作用是随 Servlet 容器同时启动 db4o 数据库,并作为 Server 运行,以便在运行时通过 db4o 对象管理工具进行管理,了解 db4o 的 Server/ Client 模式的具体含义,请参考 《开源面向对象数据库 db4o 之旅: db4o 查询方式》 。最后,不要忘了在 web.xml 中加载 Db4oInit Servlet。 
  Db4oInit 的 init 方法,打开一个名为"auto.yap"的 db4o 数据库文件,不用担心,如果是因为第一次运行而没有该文件,db4o 会自动创建,除了数据库文件,还要加上端口号,在这里我们使用 1010,最后进行口令授权。 
  package com; 
  import javax.servlet.ServletException; 
  import javax.servlet.http.HttpServlet; 
  import com.db4o.Db4o; 
  import com.db4o.ObjectServer; 
  public class Db4oInit extends HttpServlet {
  private ObjectServer server; 
  public void destroy() {
  server.close(); 
  super .destroy(); 
  }
  public void init() throws ServletException {
  this .server = Db4o.openServer( " auto.yap " , 1010 ); 
  this .server.grantAccess( " admin " , " 123456 " ); 
  }
  } 
  ContactService 类是 db4o 的 Client 端,用于响应业务操作,包含了最基本的 CRUD 操作。值得注意的是 getPeopleXml 方法,我们利用 db4o 的 QBE 方式查询数据库,如果您愿意,还可以使用 SODA、NQ 方式查询数据库。之后利用 dom4j 进行对象的序列化,在此笔者还推荐 XStream 结合 java 5 的 annotation 进行序列化。新增、删除、修改很简单,不再敷述,请下载程序源码查看,注意每次操作完之后 commit 事务即可。
  package com; 
  import org.dom4j.Document; 
  import org.dom4j.DocumentHelper; 
  import org.dom4j.Element; 
  import com.db4o.Db4o; 
  import com.db4o.ObjectContainer; 
  import com.db4o.ObjectSet; 
  import bo.People; 
  import java.io.IOException; 
  public class ContactService {
  private static final String HOST = " localhost " ; // server host name 
  private static final int PORT = 1010 ; // server port 
  private static final String USER = " admin " ; // server username 
  private static final String PASSWORD = " 123456 " ; // server password 
  /** 
  * retrieve data from db4o as XML String 
  * @return XML String
  */ 
  public String getPeopleXml(){
  ObjectContainer db = null ; 
  try {
  db = Db4o.openClient(HOST,PORT,USER,PASSWORD); 
  People peo = new People(); 
  ObjectSet < People > objectSet = db.get(peo); 
  Document peplDoc = DocumentHelper.createDocument(); 
  peplDoc.setXMLEncoding( " UTF-8 " ); 
  Element rootNode = peplDoc.addElement( " root " ); 
  for ( int i = 0 ; i < objectSet.size(); i ++ ){
  Element peplNode = rootNode.addElement( " node " ); 
  People eachPeople = (People)objectSet.get(i); 
  peplNode.addAttribute( " userId " ,String.valueOf(eachPeople.getUserId())); 
  peplNode.addAttribute( " userName " ,eachPeople.getUserName()); 
  peplNode.addAttribute( " userPhone " ,eachPeople.getUserPhone()); 
  peplNode.addAttribute( " userEmail " ,eachPeople.getUserEmail()); 
  peplNode.addAttribute( " userAddress " ,eachPeople.getUserAddress()); 
  }
  return peplDoc.getRootElement().asXML(); 
  } catch (IOException e){
  e.printStackTrace(); 
  return " <error/> " ; 
  } finally {
  if (db != null ){
  db.close(); 
  }
  }
  }
  } 
  peopleoperat.jsp 代码也相对简单,请下载程序源码查看。 
  页面代码 
  要编写 OpenLaszlo 服务器 能运行的代码,就必须使用 LZX 语言,LZX 是一种面向对象的基于标记的语言, 利用 XML 和 JavaScript 语法构建 RIA 表现层, 通常这些编写完成的代码会经过 OpenLaszlo 编译器进行编译,最后可作为独立的 swf 文件或部署在服务器上运行。 LZX 语言使用开发者熟悉的语法和命名方式,因此能较容易地融入现有编程环境。 
  LZX 语言具有继承、封装、多态等面向对象语言所具有的特性。通常,一个标签就等于实例化了一个类,比如 <view> 就是 LzView 的实例。值得注意的是,和基于 DHTML/JavaScript 的程序有着概念上的不同,典型的 DHTML/JavaScript 程序是直接由浏览器解析、执行嵌入其中的 JavaScript;而 LZX 中的 JavaScript 则是在 OpenLaszlo 服务器端编译成客户端 Flash 解析引擎能运行的字节码,再下载到浏览器执行的(swf 文件 )。
  LZX 程序是运行在名为 canvas 的可视对象基础上的,也就是以 <canvas> 开始并以</canvas> 结束的标签中。在 canvas 中,有许多 view,这些 view 嵌套着业务逻辑、可视化特性、可编程属性、尺寸、位置、背景颜色、不透明性、可点击性、伸缩性,等等信息。view 也可以包含资源,例如图像或视频,也可以动态绑定任意 XML 格式数据集。
  现在我们就进入代码部分,首先观察前三行:
  < canvas debug ="true" height ="580" width ="780" title ="Hello db4o, openlaszlo" fontsize ="12" > 
  < debug x ="0" y ="400" width ="300" height ="200" /> 
  < splash /> 
  第一行代码向我们表明了 LZX 语言的面向对象特性,canvas 对象的 debug 属性为了让程序调试时能在 debugger 窗口打印出调试信息,height、width 属性分别指定了 canvas 对象的高和宽,超过这一大小,将不会被显示,title 属性和 HTML 中 title 标签功能一样,fontsize 属性作为一个全局参数,如果没有明确指定,那么在 canvas 中所有的 view 都将使用该字体大小。第二行代码实例化 Debug 对象,并规定了 debugger 的高和宽,除此以外,还定义了窗口出现的 x(横坐标)、y(纵坐标),这些都是相对坐标。第三行定义了 splash 对象,该对象是加载应用程序时的进度条。 
  LZX 还提供了强大的绘图功能,下面就让它小试牛刀吧:
  < drawview name ="banner" width ="780" height ="50" > 
  < handler name ="oninit" > 
  this.beginPath(); 
  this.lineTo(780, 0); 
  this.lineTo(780, 50); 
  this.lineTo(0, 50); 
  this.lineTo(0, 0); 
  this.closePath(); 
  var g = this.createLinearGradient(0,0,0,50); 
  this.globalAlpha = 0; 
  g.addColorStop(0, 0x666666); 
  this.globalAlpha = 1; 
  g.addColorStop(1, 0xFFFF00); 
  this.fillStyle = g; 
  this.fill(); 
  </ handler > 
  </ drawview > 
  在本应用中,我们要实现的是一个渐变的黄色 banner。drawview 类是专门绘图的,handler 类捕获了 oninit 内置事件。我们这样设想:手中有只画笔,从某点开始,然后按照一定路径进行边框描绘,最后填充颜色。同理,this.beginPath() 设置画笔的开始点(0,0 坐标),然后绘制直线到 780,0 坐标,接着再绘制到 780, 50 坐标,然后闭合方框(this 表示 drawview 自身对象实例),this.createLinearGradient(0,0,0,50) 方法是在按照 x0, y0, x1, y1 这种路径进行梯度过渡,this.globalAlpha、g.addColorStop() 是一系列的颜色填充设置,从 0x666666 颜色均匀过渡到 0xFFFF00 颜色,最后 this.fillStyle = g 应用该设置,this.fill() 填充即可。 
  有了以上基础,我们开始解析可视化组件,下面是构造边框为绿色的 bordergreenbox 类:
  < class name ="bordergreenbox" extends ="view" x ="1" y ="145" width ="${canvas.width-2}" bgcolor ="0x9ae900" > 
  < view name ="innerbox" bgcolor ="0xf4f4f4" x ="1" y ="1" height ="${parent.height-2}" width ="${parent.width-2}" /> 
  </ class > 
  class 标签是自定义类的基础,name="bordergreenbox" 属性为类命名,extends="view" 声明 "bordergreenbox"类是继承自"view"(view 是最常用的类,用于组织包含在其中的元素的交互),相应的也就继承了"view"所有的属性和方法。定义宽度时用到了"${}"约束符,这意味着"bordergreenbox"的宽度要受到"canvas.width-2"的约束,接着设置背景为绿色 bgcolor="0x9ae900"。为了能达到绿色边框的效果,我们在其中嵌入另一个 view,再设置颜色、相对坐标、高、宽。 
  以下部分是在构造 newPeople 类,用于让用户输入基本信息:
  < class name ="newPeople" extends ="view" fontsize ="13" visible ="false" > 
  < simplelayout spacing ="4" axis ="x" /> 
  < text > 姓名:</ text >< edittext name ="userName" width ="60" /> 
  < text > 电话:</ text >< edittext name ="userPhone" width ="100" /> 
  < text > 电子邮件:</ text >< edittext name ="userEmail" width ="140" /> 
  < text > 地址:</ text >< edittext name ="userAddress" width ="230" /> 
  </ class > 
  和 bordergreenbox 类不同的是,newPeople 类引入了新属性 visible="false",它的作用是让newPeople 不可见,如果不设置该属性则默认为可见。我们还引入了 simplelayout 类,它的作用是均匀分布 newPeople 类中所有的对象,spacing="4" 是在定义间距为 4,axis="x" 定义按照横向分布。text 类是用来嵌入文字的,且支持嵌入 <a>、<b>、<font>等 HTML 标记,而 edittext 的作用则类似 HTML 中的 input 标签。 
  如何访问 JSP 提供的数据源呢?在这个应用中,分别构建了两个数据集,db4odata 用来获取返回的列表数据,peopleoperate 进行业务操作,下面主要分析 db4odata:
  < dataset name ="db4odata" src ="peopleoperat.jsp?action=getPeopleData" type ="http" request ="false" /> 
  < datapointer name ="db4odtpt" xpath ="db4odata:/*" > 
  < handler name ="ondata" > 
  canvas.bgview.rowcontainer.datapath.setPointer(thi s.p); 
  canvas.loader.setVisible(false); 
  Debug.write("data loaded!"); 
  </ handler > 
  </ datapointer > 
  dataset 是数据访问类,src 作为资源访问路径指向 JSP 页面,并规定type 为 http 协议,当request="false" 时,必须通过调用 doRequest() 方法才能访问资源并获取数据,而为"true"时,则会自动访问资源,一般应设置为"false"。接下来用到了 datapointer 类,datapointer 是 dataset 的数据指针,并遵循 XPATH 语法规范访问数据,xpath="db4odata:/*" 定义 XPATH 的路径,既 db4odata dataset 的所有子路径。handler 类捕获 ondata 事件(ondata 是 datapointer 对象内置事件),并通过"."运算符为 bordergreenbox 类的实例 bgview 设置数据源,再隐藏一个名为 loader 的对象,代码如下:
  < text name ="loader" x ="2" y ="2" text ="loading" /> 
  不错,loader 对象仅仅写下"loading...",这是为了改善程序的互动效果。接下来分析 bordergreenbox 类实例 bgview,bgview 包含了两个 view 对象。以下代码向我们展示了第一个 view,它的作用是提供列名:
  < view x ="1" y ="15" fontsize ="14" fgcolor ="0xFFFFFF" fontstyle ="bold" width ="${canvas.width-4}" height ="25" bgcolor ="0xdd8910" > 
  < text x ="40" > ID </ text > 
  < text x ="140" > 姓名</ text > 
  < text x ="260" > 电话</ text > 
  < text x ="410" > 电子邮件</ text > 
  < text x ="620" > 地址</ text > 
  </ view > 
  第二个 view 对象 rowcontainer,刚才我们分析 db4odata 数据源集时捕获的 ondata 事件吗?不错,一旦接收到数据,rowcontainer 也就从 name="db4odtpt" 的数据指针中获取了数据: 
  < view name ="rowcontainer" x ="1" y ="39" datapath ="" width ="$once{parent.width-2}" height ="$once{parent.height-40}" clip ="true" > 
  < view name ="columns" datapath ="${parent.datapath}" width ="$once{parent.width-2}" > 
  < simplelayout axis ="y" spacing ="1" /> 
  < selectionmanager name ="selector" toggle ="true" /> 
  < view datapath ="*" width ="$once{parent.width}" bgcolor ="0xffffff" onclick ="parent.selector.select(this); " > 
  < text x ="0" datapath ="@userId" width ="110" /> 
  < text x ="115" multiline ="true" datapath ="@userName" width ="100" /> 
  < text x ="220" multiline ="true" datapath ="@userPhone" width ="130" /> 
  < text x ="355" multiline ="true" datapath ="@userEmail" width ="180" /> 
  < text x ="540" multiline ="true" datapath ="@userAddress" width ="220" /> 
  < method name ="setSelected" args ="amselected" ><![CDATA[ 
  if (amselected) { 
  var bgcolor = 0xD5E4F3; 
  canvas.np.sendit.userid = this.datapath.xpathQuery('@userId'); 
  canvas.np.userName.setText(this.datapath.xpathQuer y('@userName')); 
  canvas.np.userPhone.setText(this.datapath.xpathQue ry('@userPhone')); 
  canvas.np.userEmail.setText(this.datapath.xpathQue ry('@userEmail')); 
  canvas.np.userAddress.setText(this.datapath.xpathQ uery('@userAddress')); 
  canvas.np.userName.setAttribute('enabled',false); 
  } else { 
  var bgcolor = 0xFFFFFF; 
  canvas.np.userName.clearText(); 
  canvas.np.userPhone.clearText(); 
  canvas.np.userEmail.clearText(); 
  canvas.np.userAddress.clearText(); 
  canvas.np.userName.setAttribute('enabled',true); 
  }
  this.setBGColor( bgcolor ); 
  ]]></ method > 
  </ view > 
  </ view > 
  < scrollbar /> 
  </ view > 
  clip="true" 属性是为了让包含在其中的子对象之间能够很好的布局。rowcontainer 中又嵌套了 view 对象 columns,并通过父对象取得了数据路径 datapath,接着按纵向均匀布局其中的行,selectionmanager 类似 HTML 中的 select 标签,一旦选中某行将触发为其内置属性 selected 赋值为"true"。接下来的 view 才是真正显示数据列表,onclick 事件也是 view 类的内置事件,当点击了某条记录,将联合 selectionmanager 进行操作,所以在这里为 selectionmanager 传入了选中的某条记录。datapath="@userId" 用于绑定 XML 数据中的 userId 属性,并自动显示。刚才说到由于 selectionmanager 和 view 是紧密联系的,所以在这里重写了 view 的 setSelected 抽象方法,并传入了布尔类型数据。在<![CDATA[ ]]> 之间的代码,OpenLaszlo 将忽略其中的特殊字符(例如"<"符号),np 是之前我们构造的 newPeople 类的实例,接下来会讲到,而 canvas.np.sendit.userid = this.datapath.xpathQuery('@userId') 则是在进行赋值操作,虽然 newPeople 类的实例是不可见的,但却隐含的传入了数据,canvas.np.userName.setAttribute('enabled',false) 是动态创建的属性,为了区分"新增"、"修改"操作(新增可编辑"用户名"而修改则不能)。var bgcolor 是在声明局部变量,和 Java 语言不同的是,if 语句内声明的局部变量也能在语句之外调用,所以 this.setBGColor(bgcolor) 不会出现任何异常。 
  想必大家很关心 newPeople 类实例 np 是什么样子,接下来会讲解到如何添加和修改数据并提交给 JSP 处理: 
  < newPeople name ="np" y ="85" > 
  < button name ="sendit" height ="24" width ="40" text ="提交"> 
  < attribute name ="userid" value ="0" /> 
  < attribute name ="action" value ="null" /> 
  < handler name ="onclick" ><![CDATA[ 
  var username = parent.userName.getText(); 
  var usermobile = parent.userPhone.getText(); 
  var useremail = parent.userEmail.getText(); 
  var useraddress = parent.userAddress.getText(); 
  var usernamenabled = parent.userName.getAttribute('enabled'); 
  function send(action){
  peopleoperate.setQueryParam('action',action); 
  peopleoperate.setQueryParam('userId',userid); 
  peopleoperate.setQueryParam('userName',username); 
  peopleoperate.setQueryParam('userPhone',usermobile ); 
  peopleoperate.setQueryParam('userAddress',useraddr ess); 
  peopleoperate.setQueryParam('userEmail',useremail) ; 
  peopleoperate.doRequest(); 
  canvas.loader.setVisible(true); 
  parent.setVisible(false); 
  canvas.bgview.setY(85); 
  }
  if (username!='' && usermobile!='' && useremail!='' && useraddress!=''){
  if (action == 'add' && usernamenabled == true){
  Debug.write('addPeople'); 
  send('addPeople'); 
  } else if (action=='update'){
  Debug.write('updatePeople'); 
  send('updatePeople'); 
  }
  } 
  userid = 0; 
  ]]></ handler > 
  </ button > 
  </ newPeople > 
  在此我们引入了 button 类,接着构造了两个属性,userid 用于在修改时传递用户 ID,而 action 则用于确定是何种业务操作。接着捕获了 button 类的 onclick 事件,声明局部变量以便接下来发送,function send(action){…} 是构造的内部方法,用于发送请求,peopleoperate.setQueryParam() 是在对 peopleoperate 数据集创建请求参数,最后 peopleoperate.doRequest() 发出请求。构造好内部方法后,开始判断是哪种业务操作,并分别传入 'addPeople' 和 'updatePeople' 参数,待提交完成后 parent.setVisible(false) 隐藏 np。 
  我们在前面提到了当点击了 columns 对象中的某一行将自动为 np 对象填入值,而这个时候 np 是隐藏的,不错,需要增加一个按钮来显示 np 以便进行修改:
  < button name ="updtuser" x ="60" y ="55" height ="24" width ="40" text ="修改"> 
  < handler name ="onclick" > 
  parent.np.setVisible(true); 
  parent.bgview.setY(115); 
  canvas.np.sendit.action = 'update'; 
  </ handler > 
  </ button > 
  新增和修改的操作差不多,而删除则传入用户 ID, peopleoperate.setQueryParam('action','delPeople') 直接删除。 
  到此,页面代码也完成得差不多了,启动您的服务器。 
  Tips 
  在开发 OpenLaszlo 过程中会遇到不少意想不到的问题,最常见的是提交数据后 debugger 打印出"data conversion error……"信息,检查程序后未发现任何异常,很让人困惑,其实你只需在服务器端返回一个简单的 XML 即可,哪怕是"<ok/>"标签。 
  您的应用程序在运行时是可以随时点击鼠标右键查看源代码的。 
  这对安全构成了威胁,特别是部署后实际运行的应用。OpenLaszlo 为我们考虑到了这点,只需修改被部署的应用的"WEB-INF\lps\config\lps.properties"文件,把"allowRequestSOURCE"参数设置为"false"即可。 
  提高 OpenLaszlo 开发效率原则: 
  1. 只做自己擅长的事 
  OpenLaszlo 只擅长做表现层,不要奢求在界面上处理一些复杂逻辑,这些要交给后台处理。也不要用它来做类似于博客等以文字为主的应用,体现不出优势,反而体现出劣势。 
  2. 做好自己该做的事 
  类似于客户端数据校验的功能,前台该做好的,就不要交给后台去判断数据是否有效,前台每次提交都要保证自己是没有问题的,和后台的结合应该是无障碍的。 
  3. 不要过分追求效果 
  不要为了 RIA 而 RIA,界面的过多动态效果,只会让用户眼花缭乱,而且加大了代码量,增加了性能问题,损害了用户体验,只有简单中有一点新奇、静中有动才是境界。 
  提高 OpenLaszlo 运行效率原则: 
  1. dataset 的请求(request)属性永远是 false 
  只有在事件中才进行 doRequest()。 
  2. 尽量少用约束符${}来指定视图间的位置关系 
  比如:<view name="myview" x="${parent.b.x}" .../> 因为程序在初始化过程中要评估表达式的值,而且生成约束 constraints,这样对性能产生很大影响。 
  3. 需要数据来生成视图内容的组件尽量不用严格数据绑定 
  这样做是为了减少程序编译时间合减少服务期端传送过来的文件尺寸。正确的做法是将组件的 datapath 置为空,即定义组件的 datapath="",而在用户事件或者在 datapointer 中的 ondata 事件中用 component.datapath.setPointer(this.p) 中进行运行时绑定。 
  4. 通过事件给组件填充数据 
  combobox 、list 等组件的数据只在需要时填充,通过打开窗口或者点击按钮的事件来为这些组件填充内容。只要填充了一次,下次如果数据没变,就不会再重复生成视图。 
  5. 使用 initstage="defer" 
  OpenLaszlo 官方文档推荐使用 initstage="defer" 来阻止某些不是马上用到的视图的生成,而在需要的时候才 complete,但笔者试过,不太好掌握时机,而且会让程序变的互相耦合,效果不甚理想。 
  6. 使用 dataoption="lazy" 
  list 组件有一个很有用的属性:dataoption="lazy",这个属性可以使列表中的数据更新起来非常迅速,尤其是在大数据量的情况下。它的原理在于把部分视图进行了缓存,而不是全部销毁和新建,可惜 tree 组件对于这个属性不管用。 
  7. 尽量降低视图的层次 
  尽可能的减少视图的嵌套层次,能直接放在 canvas 下,就不要放在其他视图里面,而且window 和 modaldailog 应该严格的直接放在 canvas 里面。这样做是为了加快程序的渲染速度,并且简化编程时路径引用,方便查看代码结构。 
  8. 尽量少用 state/animator 
  用这些会增加内存占用和代码量,而用 node 的 animate 方法却可以轻松的控制视图运动,而且没有额外的内存占用。 
  9. 控制单个 canvas 文件的代码规模 
  一个 canvas 文件代码行数最好控制在 1000 行以内,其中 include 进来的方法、资源、自定义组件的代码数目不算在内,这样做是为了获得较快的界面初始化时间,和方便的代码维护。 
  10. 尽量采用 SOLO 方式部署 
  如果不需要 RPC 等特殊功能,建议采用 SOLO 方式部署应用,将已经写好的 OpenLaszlo应用编译成 swf 文件,在 html 文件中包裹,这样可避免用户第一次请求 lzx 文件的长时间等待,也避免了服务期重起后重新编译 lzx 文件,还可以减少 OpenLaszlo Server 部署时对服务器空间的占用(尽管才十几兆)。 
  11. 模块化应用 
  将具有独立功能的应用模块单独分离出来,即用一个包含 canvas 的 lzx 文件配合其他组件来实现一个小模块,各个模块之间导航用 loadURL() 来完成,各个模块共享 Session 以及后台数据,实现模块之间的通讯。 
  结论 
  通过上面的介绍,想必您已经体会到 OpenLaszlo 与 db4o 结合起来做程序是多么的有趣。如果在不借助第三方框架,用传统的 JSP+JavaScript 与 JDBC 技术开发,相信其代码量会远远超过前者。OpenLaszlo与 db4o 的设计目标都是为节约开发周期而努力,相信他们也做到了,剩下的就看开发者是如何利用其优势的,您准备好了吗? 
  关于作者 
  Rosen Jiang 来自成都,是 db4o 和 OO 的忠实 fans,RIA 倡导者,是 2007 年 db4o 的 dvp 获得者之一。你可以通过 rosener_722@hotmail.com 和他联系。 
  Lwz7512 来自北京 ,是一名 OpenLaszlo Developer,他是 OpenLaszlo 在中国的User Group负责人,也是Openlaszlo中国开发者社区创办者, 你可以通过 rabbit69@126.com 和他联系。
分享到:
评论

相关推荐

    openlaszlo本地帮助文档

    LZX允许开发者以声明式的方式描述UI元素,同时支持编程逻辑,结合了静态布局与动态行为。LZX的灵活性在于它可以编译为Flash或JavaScript,这意味着OpenLaszlo的应用程序可以在多种浏览器和操作系统上运行,包括桌面...

    OpenLaszlo-SAMSIG-05.ppt

    ### OpenLaszlo:领先的开源富互联网应用开发平台 #### 一、项目概述与历史 OpenLaszlo 是一个开放源代码平台,旨在为全球范围内的互联网提供丰富的应用程序开发及交付服务。它由 Laszlo Systems 公司于 2001 年...

    Applet & Openlaszlo

    5. **文件操作**:如果需要在客户端进行文件上传或下载,Applet可以利用其对本地系统的访问权限,处理文件操作,然后通过通信接口与OpenLaszlo应用共享结果。 6. **性能优化**:通过Applet与OpenLaszlo的集成,可以...

    openlaszlo-4.9.0-windows-dev-install.part2.rar

    openlaszlo应用程序开发使用的是基于XML的LZX语言,它可以被编译成DHMTL,SWF等格式。 openlaszlo可作为openmeetings客户端的编译。 因安装程序90+MB,所以切分为两个压缩包。 openlaszlo-4.9.0-windows-dev-install....

    OpenLaszlo —— 一个快速构建和部署富 Internet 应用程序的平台

    OpenLaszlo —— 一个快速构建和部署富 Internet 应用程序的平台 -- Linux,C,C++,Java,Ajax,XML,perl,php,python,ruby,MySQL,Gnome,KDE,Qt,Gtk,bash,shell,嵌入式,网络,信息安全,操作系统,数据结构,编译原理

    openlaszlo-4.9.0-windows-dev-install.part1.rar

    openlaszlo应用程序开发使用的是基于XML的LZX语言,它可以被编译成DHMTL,SWF等格式。 openlaszlo可作为openmeetings客户端的编译。 因安装程序90+MB,所以切分为两个压缩包。 openlaszlo-4.9.0-windows-dev-install....

    openlaszlo-4.7.3-windows-dev-install (1).exe

    openlaszlo应用程序开发使用的是基于XML的LZX语言,它可以被编译成DHMTL,SWF等格式。 是openmeetings视频会议系统的默认开发编译工具。

    openlaszlo计算器

    这是用Openlaszlo开发的计算器程序,可以实现基本的计算操作。 我是刚学openlaszlo,欢迎朋友们提出宝贵意见!

    Laszlo技术手册续

    2. **配置步骤**:首先,下载OpenLaszlo Server的servlet文件(如openlaszlo-3.3.3-servlet.war),将其解压并放入Tomcat的webapps目录下。启动Tomcat后,LPS会被自动部署。接着,可以创建LZX文件并进行测试。 **...

    论文研究-使用OpenLaszlo构建J2EE中的RIA程序 .pdf

    使用OpenLaszlo构建J2EE中的RIA程序,高春阳,龚群侃,当前,Web 应用程序就要进入了一个新的时期,富互联网客户端(RIA ,Rich Internet Application) 以其极大地用户交互性、优秀的外观设计、良好��

    OpenLaszlo-开源

    这使得开发者能够利用OpenLaszlo来创建跨平台、兼容多种浏览器的富互联网应用。该项目的官方站点在http://openlaszlo.org,这是一个宝贵的资源库,包含了文档、示例代码和社区支持,对于学习和使用OpenLaszlo的人来...

    geoar:WMSWFS OpenLaszlo 客户端

    Geoar - WMS/WFS OpenLaszlo 客户端GeoAr 是 WMS 和 WFS 服务的富客户端实现。 它是在 LZX (OpenLaszlo) 上开发的,因此它向用户的浏览器提供 dhtml 或 flash,从而提供在它们之间进行选择的机会,但只有一个服务器...

    Openlaslzo+jsf

    ### Openlaszlo+JSF:SWF动画制作与Struts框架整合配置详解 #### 一、OpenLaszlo简介及SWF动画制作 **OpenLaszlo**是一款开源的跨平台开发工具,用于创建RIA(Rich Internet Applications)。它允许开发者使用一种...

    改造OpenMeetings成为Flash视频会议室(三)

    1. **类的继承、定义与使用**:在OpenLaszlo中,可以创建自定义组件并实现继承,以便重用和扩展已有组件的功能。 2. **事件与触发**:OpenLaszlo支持事件驱动编程,允许组件之间通过事件进行通信,如点击按钮触发...

    spket1.6.18

    Spket对OpenLaszlo的支持意味着开发者可以享受到与JavaScript同样的代码辅助功能,如智能感知、代码导航和重构,这使得OpenLaszlo的开发过程更为流畅。 安装"Spket1.6.18"插件到Eclipse后,用户界面会得到扩展,...

    Laszlo与web工程

    【Laszlo 与 Web 应用】 Laszlo 是一个开源项目,它遵循 GNU General Public License (GPL) 协议。该项目的核心是 LZX 文件,这是一种标记语言,用于构建富互联网应用程序(RIA)。LZX 文件在 Laszlo Presentation ...

    huoyan.zip_火焰识别c++

    如果这个项目与OpenLaszlo有关,那么可能是将C++编写的火焰识别算法集成到OpenLaszlo应用中,以提供更丰富的视觉体验。 文件列表中的“实例77”可能是一个示例项目或者代码片段,展示了如何使用提供的C++ API来实现...

    openmeeting安装

    9. **OpenLaszlo Server**: OpenLaszlo用于编译OpenMeeting的客户端界面。下载并安装相应版本的OpenLaszlo服务器,然后进行配置。 10. **OpenMeeting源代码**: 通过Subversion (SVN) 从指定URL获取OpenMeeting的源...

    Laszlo技术手册

    手册详尽地介绍了Laszlo的核心概念、安装配置、LZX语言、事件处理、动态效果、约束机制以及OpenLaszlo的开发实践,旨在帮助读者快速掌握Laszlo并应用于Web工程。 Laszlo是一种开源的富互联网应用程序(RIA)开发...

    改造OpenMeetings成为Flash视频会议室(一)

    这个过程涉及到多个技术组件,包括JDK、Red5、OpenMeetings、OpenLaszlo、MySQL以及版本控制工具。以下是对这些技术的详细介绍: 1. **JDK (Java Development Kit)**:作为基础,JDK 1.5 或更高版本是必要的,因为...

Global site tag (gtag.js) - Google Analytics