Hybridizing HTML
November 8, 2007
将窗体数据提交至服务器
一旦用户按下提交按钮,就调用了主程序的submit()函数(这得以通过有效性检查为前提)。你可以看到很多Flex程序范例是利用HTTPRequest对象使用更为复杂的方式来与服务器进行交互。这类Flex UI启动一次和服务器之间的会话并在应答报文中更新其自身(和AJAX一样),这样用户就不必在页面之间不断地来回跳转了。
这是一种较好的实现方法,但在本例中我将使用一个过渡方案,你可以使用已有的网页,只改变输入数据的窗体而保持其他内容不变。这可能会给人一种倒退的感觉,但使用一个老的web例子理解起来会更容易些。
同样地,在调用服务器URL时窗体中的数据需要被传送到服务器那边。你可以使用GET来完成,但本例中我们使用POST。Flex提供了navigateToURL()函数实现了调用和跳转至服务器返回页面的功能。
使用该函数必须传递一个URLRequest对象,这个对象包含目标URL,还可能含有以URLVariables形式绑定的数据。所以submit()首先做的是创建并设置URLVariables对象,将其绑定在URLRequest上,后者是navigateToURL()的第一个参数;然后告诉它如何在浏览器上显示处理后的网页,一般会用到打开一个新窗口的"_blank"或使用当前窗口的"_self"。出于安全考虑在这个weblog平台上我不能使用"_self",所以得允许弹出窗口才能看见结果。
服务器端
为了简化问题,我们假定你仅用等价的Flex窗体取代一般的web页面窗体。这意味着一个页面中只有一个窗体和提交按钮。尽管对于Flex这么做没有太多实际意义,因为Flex组件可以轻松处理浏览器在响应提交时返回的数据。老实说,你也可以用AJAX实现,但没有Flex这么nice。
在我们的例子中,当用户按下提交按钮,Flex窗体会像HTML窗体那样提交数据。所以你可以在服务器上使用任何你所喜爱的后台技术,比如Python、Perl、Java或Ruby等。我的网站简单用了下PHP技术,这里也会用它。下面是目标页面的代码:
<?php include "standard.php"; head("Trip Information from Flex Form"); ?>
<h1>Trip Information<br>from Flex Form</h1>
<table cellspacing="20">
<?php
foreach($_POST as $key => $val)
printf("<tr><td>%s</td><td>%s</td></tr>/n", $key, $val);
?>
</table>
<?php foot(); ?>
第一行和最后一行是我自己加进去的,它会在网站所有页面上显示(意思是网站还处于调试阶段,还有大量页面不合规范)。它们连同格式表单(style sheets)建立了一套标准页面和页脚信息,可以贯穿整个网站进行修改和显示。
该表由用PHP编写的HTML页面创建的,大部分代码除了foreach外对C程序员来说应该都比较熟悉。在这里foreach语句是从"POST"数据中提取每个key值对并各自将它们分成$key和$value两部分。
这段代码的关键之处在于它对任意CGI请求也是适用的,无论该请求来自于普通HTML窗体还是Flex窗体。这就意味着你在改进站点时可以使用Flex,也可自由选择何时使用HTML窗体、何时使用Flex窗体。
在HTML内嵌入Flash
很多年前我在主页中曾嵌入过一小段Flash动画。我首先发现的是让它正常运行是如此困难,实际上我也没运行成功过。我想这是在Flash上欠缺经验的缘故。但当在HTML中嵌入Flash时竟也如此的大费周折,几乎遇到了浏览器的所有Bug和兼容性问题。
这是我看过的最好的一篇文章,总结了各种情况并描述对应解决方法,其本身也是经历了一场极其重要的演变过程。
最好的方法看来就是使用JavaScript库,它包含了所有针对跨平台和跨浏览器问题的必要的测试和解决办法。而且个别人号称以有且仅有一种的方法解决了某些问题。所以,你大可以忽略一些纷乱的细节而“以最简单的方式去做可能运行成功的工作。”
上面提到的文章详细介绍了JavaScript库的演化过程。简单的说就是有一个名为SWFObject和UFO的对象,它们被统一到SWFFix上来,现在改称为SWFObject。这可能会有点令人糊涂:SWFObject 1.5是该项目最后一个版本,一开始就是用的这个名字,而SWFObject 2.0是到目前为止的beta 6版。你可以在这里下载。
即使是beta版,SWFObject的第二选择的简易性也是格外引人注目,所以我将用到它。你只需加入swfobject.js,然后调用swfobject.embedSWF()即可。这里要提供SWF文件和SWF文件在页面中的存放位置div id来作为参数,还包含宽度、高度和Flash VM的最低版本。有了这个目标div,你就可以向里面加入任何内容了。若无法载入SWF就会出现可选项。
这是我以前写过的将窗体嵌入进该页面的代码:
<script type="text/javascript" src="http://www.mindviewinc.com/demos/flex/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("http://www.mindviewinc.com/demos/flex/Traveler.swf", "myContent", "500", "300", "9.0.0 ");
</script>
<div id="myContent">
<p>The Flex form should appear here.</p>
</div>
有关使用swfobject的细节在前面提到的网站中可以找到。
如果有人厌倦了JavaScript,他们也就不能从中受益。如果是这样,AJAX对他们也没有意义。如果是这种情况,这些人大概同样不会对在线购物一类的事物产生太大兴趣。
窗体
一个活生生的例子已经给你了。注意,空栏会显示为红色线框,鼠标掠过这些栏时会提示错误消息。如果你设置的返程日期早与启程日期,也会提示一个错误消息。
当全部正确完成表单后,提交按钮就会变亮,然后点击就可以看到结果页面了(需要允许弹出窗口)。
Flex窗体就会在这里显示。
结论
看看这个简单漂亮的结果。不仅Flex代码本身编写起来比HTML简单得多,你也可以:
l 获得Flex组件提供的丰富功能,它比AJAX提供的功能看起来更nice。
l 在客户端实现所有有效性检查和约束逻辑以提供更加优秀的用户体验,编写和重用这种逻辑要比JavaScript简单多了。
l 无需进行测试就可自动拥有跨平台的行为特性(节省了大量时间和人力)
l 创建自己的组件并加入到混合架构中以获得同样的益处。
与HTML相比它还有一个重大改进,那就是自动化软件(robots)无法检测到你的提交窗体,因此可以减少大量垃圾信息和恶意提交行为。
就个人而言,我仍将“做最简单的事情”,设计平淡无奇的链接和HTML窗体,只要这种简单页面能够运行正常。但是我也避免加入一些简单到如弹出日历的AJAX组件到网站中,因为当作为消费者进行体验时,我的感觉真的太糟糕了,实在不想冒这个风险。然而,考虑到Flex组件的可靠性和一致性,我在设计富web用户界面时又会比较大胆,因为我知道使用Flex技术不会有痛苦和折磨人的经历。
感谢James Ward对本文提供的技术帮助。(全文完)
(原文链接网址:http://www.artima.com/weblogs/viewpost.jsp?thread=213902)