China Open source community
站内导航:

 
 
 
当前位置: 首页 >> 程序设计 >> 使用OpenLaszlo创建Web富客户端
 

使用OpenLaszlo创建Web富客户端

作者:      来源:ibm     发表时间:2006-05-17     浏览次数:      字号:    

OpenLaszlo 是一种富客户机应用程序架构,使用 Macromedia Flash 作为部署载体。OpenLaszlo 依赖 JavaScript 来表达逻辑,并提供了传统 Flash 开发方式无法比拟的一些优点,包括高级的 UI 约束系统、面向对象的设计方法学以及内置的对 Web 服务和各种风格的远程过程调用(Remote Procedure Call,RPC)的支持。本文详细论述了 OpenLaszlo 的基本概念,并给出一些示例场景,展示了 OpenLaszlo 解决方案的优势。

近来 Web 开发领域的一个焦点是将富客户机体验引入 Web。Asynchronous JavaScript and XML (Ajax) 使开发人员和用户拓宽了对 Web 的认识,俨然有取代标准桌面富客户机之势。然而,Ajax(以及当前的浏览器技术)却在以下几个方面存在局限性:

  • 提供带有大量动画的用户界面。
  • 轻松地提供能在多种浏览器,包括旧浏览器上显示的标准表示法。
  • 轻松地实现某些类型的应用程序,包括动态建立的应用程序。

但是,这些只是 OpenLaszlo 所擅长的一部分。在深入探讨这种架构之前,首先我们花点时间来讨论一下什么 OpenLaszlo。

Laszlo 是 OpenLaszlo 所使用的一种语言,这种语言通过说明性方法,用 XML 和 JavaScript 来创建部件或整个应用程序。这种标记语言与脚本语言的合并类似于目前的 HTML/JavaScript 组合。然而,Laszlo 不是通过浏览器在客户端来解释语言,而是在服务器端将语言转换成 Macromedia Flash 格式。这样实际上就自动提供了跨浏览器支持,因为 Flash 提供了一个标准运行时。由于 Flash 格式是基于矢量的,因此允许使用非常灵活多变的用户界面组件,并且这些组件可以大量重用。

然而,OpenLaszlo 还不止这些。OpenLaszlo 还受到一个可选的服务器端容器,即 OpenLaszlo 服务器的支持,后者提供了对远程过程调用、Web 服务和 transcoding 服务(负责将较长的 MP3 文件以流的方式传送给用户之类的事情)的广泛集成和支持。作为一种语言,Laszlo 还采用了一些令人兴奋的概念和设计方法学,以便在数分钟内创建出真正可重用的组件。这种组件拥有令人喜爱的视觉效果,并且为用户所熟悉。图 1 给出了一个例子,这是用 OpenLaszlo 创建的一个股票行情自动收录器应用程序的一个 UI。


图 1. 一个示例 OpenLaszlo UI
一个示例 OpenLaszlo UI

阅读本文并不需要以了解 Flash 为先决条件。但是应该对 JavaScript 有个基本的理解,并知道它与传统的面向对象编程语言的不同之处。此外,如果您理解基本的面向对象编程以及传统的用户界面开发 —— Swing、Standard Widget Toolkit (SWT)、Microsoft Foundation Classes (MFC) 等,那么本文将会更加有用。

组件:灵活的和可扩展的

目前,为 Web 构建可扩展的、灵活的用户界面组件的重担仍然落在开发人员身上。很多技术(定制标记库、PHP 抽象等)的存在都是为了解决一个共同的问题:开发人员常常必须组合很多 HTML 标记来为当前的 Web 应用程序创建复杂的组件。诚然,面向对象方法的价值已为众人所知,而 Laszlo 语言就包括很多面向对象的范例在里面。下面来看看一些基本的核心组件。

每个 Laszlo 应用程序都是由 XML 文件 [包含说明性用户界面(UI)信息和 JavaScript] 和资源文件(图像、嵌入式 Flash 内容和音频)组成,OpenLaszlo 将这些文件组合起来创建出最终的内容。根容器是 <canvas> 标记。<canvas> 在某些方面类似于 HTML 文档中的 <body> 标记。它可以包括一些属性,例如宽度、高度和背景颜色。源文件中的 <canvas> 是一个 XML 标记,而每个标记就是一个组件,或者是一个类 这句话的意思是,它具有相关联的方法、动画等。后面我会更详细地讲到这些组件的特性。现在,您可以通过说明性的方式使用这个标记和 <statictext> 创建规范的 "Hello, World!" 例子,如 清单 1 所示。


清单 1. 用 Laszlo 编写的 "Hello, World!" 例子

<canvas width="300" height="200" bgcolor="white">
   <statictext>Hello, World!</statictext>
</canvas>

组件利用 Flash

我暂时不介绍关于这样的代码是如何被转换和部署成 Flash 格式的细节,但是可以告诉您,OpenLaszlo 可以完成所有重要的工作。另外还需要知道的重要的一点是,OpenLaszlo 组件通常都是受 Flash 资源支持的。这意味着它们可以是基于矢量的,因此,您可以提供一个公共的组件,在各种不同的地方使用它。很多基本的组件是现成可用的。从事图形用户界面(GUI)方面工作的人对诸如 <button><checkbox><list><menu><tree> 之类的组件应该比较熟悉。

您也可以为这些基本组件提供自己的可视化资源。例如在使用标准 <basebutton> 组件时,该组件定义了 onmouseover 之类的事件,通过这些事件便可以创建自己的定制按钮。为了创建一个简单的翻滚按钮,可以使用 PNG 或 JPG,虽然这样做并不是很有趣。令人兴奋的是,您可以使用任何 Flash 文件作为资源,如此一来您可以创建可伸缩的、具有动画效果的按钮。因此,虽然在 Flash 资源中没有包含逻辑(例如 ActionScript),但是您可以利用所有 Flash 的动画概念。在此之前,为了用 Flash 创建有丰富界面的应用程序,需要熟悉大量编程方面的东西;而如果用 OpenLaszlo 进行开发,就不是这样了。当然,OpenLaszlo 系统会负责将所有的 Flash 资源合并成一个单独的 Flash 文件以供部署。在后面 “部署:proxied 与 SOLO 应用程序” 小节中我将更详细地谈到这一点。

事件和继承

像任何良好的面向对象组件一样,OpenLaszlo 组件会处理可以被声明为 inline(例如 <button onclick="buttonClicked()">)的事件(例如 onmouseover);或者,也可以在特定的组件或组件的实例上定义方法事件处理器,如 清单 2 所示。这样一来,便可以很自然地组织代码,并将匿名内部函数的概念引入到 OpenLaszlo 开发当中。考虑到任何组件都是可扩展并且是可定制的,这种技术因此变得极其强大。


清单 2. 在一个 <view> 实例上定义的事件

<canvas>
   <view bgcolor="0xcccccc" width="50" height="50">
      <method event="onmouseover">
         // Keyword this is used in the familiar JavaScript sense. 
         // Most of JavaScripts scoping
         // concepts apply directly to Laszlo
         this.setAttribute('bgcolor', 0x000000);	
      </method>

      <method event="onmouseout">
         this.setAttribute('bgcolor', 0xcccccc);
      </method>
   </view>
</canvas>

在一些不需要重用的情况下,清单 2 中的代码编写起来可能很方便,但是对于其他情况呢?幸运的是,您可以扩展任何其他已有的组件,建立一个新的组件。而您只需使用 <class> 标记定义一个新类,如下所示:


<class name="customView" extends="view">

默认情况下,所有定制的类都扩展 <view>,后者主要是作为一个容器,这一点非常类似于一个 HTML <span>。即使是简单的扩展也会有用,因为您可以使用属性来根据特定的需求定制一个组件;一些基本的例子看上去就像 CSS 一样,提供默认大小、背景颜色,等等。当然,有趣的事情不仅仅是这些。您可以在组件中包括方法、动画、构造函数属性,等等。想像一下,将完全面向对象的 UI 方法,例如 Swing,与 HTML 的容易、快速开发特性相结合,可以产生怎样的效果。







约束:强大的交互

对于富用户界面,一个重要的方面就是布局管理。Laszlo 支持(通过布局组件)很多标准的方法。例如,可以使用 <simplelayout> 元素,该元素有两个主要属性。axis 属性可用于指定布局方向,它的值可以是 x-axis 或 y-axis,而 spacing 属性可用于控制组件之间的间距。对于一个容器,可以声明多个布局,以便组合水平和垂直方向的间距。同样,这也是 Laszlo 中的一个简单而有效的概念。Laszlo 还包含网格布局和那些用于一个区域的布局,但这并不是使我对 Laszlo 刮目相看的原因。真正令人兴奋的特性是 Laszlo 约束模型(constraint model),通过它可以非常优雅地获得 UI 控件和动画效果。

大多数事件的替代物

每当 Laszlo 组件中的属性发生改变时,就触发了一个事件。正如 “事件和继承” 小节中所述,这些事件可以被侦听到。这是一个很好的特性 —— 不必为每个属性添加侦听器之类的东西 —— 但是这仍然会导致大量冗余代码。如果元素可以通过一种更方便的方式,就像电子表格中应用的依赖关系一样来使用这些属性,岂不是更好?通过约束,您就可以做到这一点。对于 Laszlo 中的任何属性,都可以为之赋予一个约束表达式(constraint expression),而不是赋予一个标准的值。约束表达式以一个美元符号开头,格式如下:


$when{ConstrainedExpression}

其中,when 的值是 alwaysonceimmediately 中的一个。如果忽略了 when,那么这个值就默认为 always,也就是说,每当 ContrainedExpression 的一个依赖关系发生改变,该约束都将重新计算。如果一个约束在初始化之后一直是静态的,那么可以将这个值设为 once,这样可以使约束只计算一次,可以提高效率。另一个值是 immediately,如果定义了结束元素,并且约束不依赖于其他对象,那么可以使用这个值来计算约束。

我们首先来看一个简单的例子。如果您想要一个大小可变的项,并且还有一个位于它中间的项,应该怎么办呢?清单 3 展示了如何实现这一点。它使用标准的 Laszlo 组件 slider 来控制矩形的大小。


清单 3. 用于控制一个矩形大小,同时影响矩形内部的另一个矩形的大小的 slider 组件

<canvas>
   <slider id="sliderItem" y="20" x="10" minvalue="50" maxvalue="300" 
           value="50"/>

   <view y="$once{sliderItem.y + sliderItem.height + 5}" 
       x="$once{sliderItem.x}" bgcolor="0xff0000" 
       width="${sliderItem.value}" height="${width}">
		
      <view bgcolor="0x0000ff" 
         width="${parent.width / 5}" height="${width}"
         x="${(parent.width / 2) - (width / 2)}"
         y="${(parent.height / 2) - (height / 2)}"/>
   </view>
</canvas>

您可以看到,由于 x<view> 的一个属性,您可以使用一个约束来设置这个值。Laszlo 使用分层的方法来标识项,parent 对象是指包含控件。通过这种语法,可以访问该结构中的所有地方,但是也可以指定 nameid 属性。两者之间的不同之处是,id 标识的是一个特定的项(因此在文档中只能使用一次),所以它可以全局使用(例如在 清单 3 中,我为 slider 控件使用一个 id 属性,然后在约束中使用那个 id${sliderItem.value})。

在这个例子中,注意用于指定有色矩形的 x 和 y 位置的约束的 once 选项的使用。图 2 给出了 清单 3 中代码的输出。


图 2. 清单 3 的输出
 清单 3 的输出

高级约束

约束对于替代简单事件和建立布局约束来说很棒,但是它们所提供的特性远远不止这些。由于可以为约束表达式设置任何 任意的属性值(包括您自己定义的值),或者在约束中使用它,因此存在很多可能。在下一节中,您将结合使用约束和 Laszlo 的动画制作系统来产生强大的结果。







动画和绘画

在现代界面设计中更关键的表示细节是动画。动画可以为界面的用户提供灵感和视觉感受。动画是 Macromedia Flash 的长项,也是 OpenLaszlo 的长项。动画也是目前不使用特殊的扩展就不能实现跨浏览器的少数几种技术之一。

动画标记

Laszlo 附带了两个元素用于帮助加快动画的开发:<animator> 元素是所有动画的基本构件,而 <animatorgroup> 则是 <animator> 项的容器。在 Laszlo 中,动画意味着在指定的一段时间内以复杂的组合改变不同属性的值。通过使用这些简单的概念和构件,几乎任何事情都有可能实现。

<animator> 元素有一个必需的名为 attribute 的属性。该属性指定动画将在哪个属性上进行操作。它还有一个必需的名为 to 的属性,该属性的值为一个数值,表示被操作的属性的终值。最后一个必需的属性是 duration,该属性指定动画所经历的时间,以毫秒计。为了方便,<animator> 元素还有一个可选的 from 属性,该属性为属性值设置起始点。通过使用这些属性,可以构造一个简单的程序,该程序以动画效果改变一个视图的宽度,如 清单 4 所示。


清单 4. 一个简单的动画例子:改变视图的宽度

<canvas>
   <view bgcolor="#ff0000" width="50" height="${width}">
      <animator attribute="width" to="200" duration="1000"/>
   </view>
</canvas>

在这个例子中将出现一个红色的正方形,并且该正方形在一秒内扩展到 200 乘 200 像素的宽度。如果试着运行这个例子,您会注意到这种运动并不是线性的。这是因为属性 motion 的默认值是 easeboth。通过使用 easeineaseouteaseboth,可以分别产生在动画开始或结束较慢或者在动画的开始和结束都较慢的效果。最后,motion 属性还可以带的一个值是 linear,该属性让动画以恒速变化。还要注意,动画是立即开始的,可以通过 start 属性来修改这一点,该属性的默认值是 true。最后,还有其他一些属性,包括用于控制步骤重复次数的属性(repeat)以及各种事件,例如 onstartonfinish 等 —— 以支持在动画完成之后添加定制逻辑。

使用 <animatorgroup> 获得复杂动画

如前所述,<animatorgroup> 就是 <animator> 元素和其他 <animatorgroup> 元素的容器。然而,增加这种容器类型肯定可以增加很多可能性。<animatorgroup> 可以和 <animator> 一样定义所有相同的属性,还可以定义一个新属性:process。如果应用到 <animatorgroup>,则之前提到的所有属性将串连起来。新的属性 process 用于控制组中各个项的执行顺序。如果它的值是 sequential,则这些项将一个接一个地执行,直到整个组执行完毕。另一个选项是 simultaneous

通过这两个选项,可以产生非常有趣的效果。例如可以有一个在屏幕上移动同时改变大小的项。由于组还可以包含其他的组,因此可以为动画定义一个好的结构和顺序。

能产生令人印象深刻的效果的约束和定制属性

看了前面的内容,您似乎会觉得动画过程看上去非常简单,作用有限。于是您可能想知道如何执行要求更复杂的计算的动画。通常,答案是利用定制属性和约束。例如,假设想要有一个在屏幕中沿着圆形轨迹运动的项。显然,您不能直接通过控制 xy 属性来产生动画效果。但是可以约束xy 的位置,使之成为某个定制属性的一个函数,这个定制属性沿着一个矩形来变化。如 清单 5 所示,如果使用约束的话,产生一个沿着圆形轨迹移动的视图非常容易。


清单 5. 结合使用约束和动画

<canvas>
   <view bgcolor="#ff0000" width="20" height="$once{width}"
      x="${radius + (radius * Math.cos(animCnt))}"
      y="${radius + (radius * Math.sin(animCnt))}">

      <attribute name="animCnt"/>
      <attribute name="radius" value="30"/>

      <animator attribute="animCnt" from="0" to="$once{Math.PI * -2}" 
            duration="1000" motion="linear" repeat="Infinity"/>
   </view>
</canvas>

通过使用这些技术,可以创建令人印象深刻的动画。您永远不必担心帧速率和其他计算,因为所有这些细节都已经为您抽象好了。此外,由于约束可能涉及多个组件,一个组件的动画可能改变其他组件的状态。

[1] [2]

编辑 webmaster

 
 
 
评论
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •  
    中国源码网 - WWW.YUANMA.ORG - 中国开放源代码社区