基于AJAX和JSF打造丰富的互联网组件之应用篇(1)(4)
在任何按键的情况下,都调用这个函数,并且根据具体的按键执行某些动作。尽管TAB键由doKeyPress函数来管理,但我们还必须确保捕获它并终止这一过程。
有关键击的另一个问题是UP和DOWN箭头键。通常情况下,这些键将引起光标在左边和右边的输入域之间的选择效果。在这个输入建议组件中,用户可以使用这些键来实现建议列表中上下选项之间的导航。
在本文中,doKeyUp函数最重要的部分是捕获所有的以输入到输入建议域中的一个新字符结束的那些击键,而不是一个Backspace键(见列表2)。在这种情况中,doKeyUp函数将调用blur()函数―它计算用户输入的值并且在发生变化的情况下激发一个change事件。我们还必须重置到输入建议域(input.focus())的焦点以便用户能继续输入更多文本。
如果一个用户输入了一个新值,doChange()函数将被激活(见列表3)。doChange()函数负责调用mabon.send()函数,传递一个包含有关用户输入值信息的Map,要调用的JSF托管bean以及该方案相应的回调函数_callback()。
_callback函数(由列表4所示),负责处理从响应对象返回的结果并且据用户输入的值创建一个建议列表。由于我们异步地与服务器进行通讯,所以我们就有一个机会―在响应返回之前―让用户输入一个新值。为确保我们能够处理这种情况,我们引入了一个计时器,它负责延迟输入探测(type-ahead)特征,直到经过一段特定时间为止。
如果值变化了(既然已经发出请求或者该值与建议的值相同),那么我们什么也不必做(见列表5)。如果该值与初始输入值相同,那么我们要把列表中建议的第一个值添加到输入域并且高亮添加到用户输入的值部分。
(三)HtmlInputSuggestRenderer
现在,我们来分析一下如何利用inputSuggest.js库所提供的客户端功能并且把它封装到一个单一的JSF组件中。在这个示例中,主要部分是JSF屏幕生成器―HtmlInputSuggestRenderer。这个生成器负责确保正确的标注被写向客户端(包括任何到其它资源例如JavaScript库,CSS,图标等的引用)。正如我们在前面文章中所讨论的,你可以使用Weblets来把这些资源打包到与你的JSF组件同一个库中。
(四)使用Weblets
开源Weblets工程(http://weblets.dev.java.net)的目的就是以一种通用的可扩展的方式来解决资源打包问题,以便所有的JSF组件创作者都可以利用它,并且它不会给Web开发者带来额外的安装负担。
总体来说,一个Weblet充当一个“调停人“的作用―它拦截客户端的请求并且使用简短的URL来从一个JAR文件中提供资源服务。不象使用servlet或过滤器(Filter)方法,一个Weblet可以在一个JAR文件内进行注册和配置。这样以来,组件库生成器、它们的资源文件和Weblet配置文件(weblets-config.xml)都可以被打包到同一个JAR文件中;而且,当组件库被升级到新版本时,你不需要单独地发布其它安装内容;而且对于Web开发者来说,不需要配置步骤。
值得注意的是,所有的Weblets提供的资源都是内部资源,仅为屏幕生成器所使用;而任何应用程序提供的资源(例如图象),都用作组件属性值并且从根上下文中作为外部资源加载。
(五)HtmlInputSuggestRenderer类
这个HtmlInputSuggestRenderer类中的两个最重要的方法是encodeBegin()和encodeEnd()方法。encodeBegin()方法(显示于列表6中)负责写这个组件需要的资源。writeScriptResource()方法和writeStyleResource()方法是HtmlRenderer所提供的便利方法并实现了“仅写一次”的功能,从而阻止多次写同一个库的情况发生―万一Web开发者把多个输入建议组件添加到页面中。
(六)使用Mabon
Mabon是一项开源的工程(http://mabon.dev.java.net)。它提供了一种方便的方式来钩住一种特别设计的生命周期―这特别适合于支持AJAX技术并且需要直接从一个支持bean中取回数据的组件,而且不需要浪费整个JSF生命周期。它还提供了一种Mabon协议(mabon:/),用于引用该支持bean和一个JavaScript工具函数。我们可以使用这种Mabon协议来发送目标URL和需要的任何参数,然后异步地从托管bean中接收数据。
(七)Mabon和JSON
正如你所知,XMLHttpRequest提供了两种响应类型―responseText和responseXML―它们可以用于取回数据。你可能会问:我何时该使用哪一种响应类型?其实,这个问题的答案依赖于是否由你自己控制响应的语法。
responseXML类型返回一个完整的DOM对象(它提供多种方式来遍历这棵DOM树),从而允许你查找需要的信息并把所作变化应用到当前文档中。当你的组件有可能影响到周围的元素而且你不能控制响应时(例如,当你与一个Web服务进行通讯时),这是相当有用的。
对于本例中的输入建议组件,你的确要控制响应并且你只想从你的组件中取回数据,而不是修改整个页面的DOM结构。responseText类型返回普通的文本,这允许你利用JSON语法用于响应。为了在组件中利用AJAX技术,JSON是一种极其有用的数据交换格式,因为它可以轻易地使用eval()函数进行分析。
eval()函数仅使用一个参数(一个JavaScript代码字符串),并一次性分析和执行这个字符串而不是分析处理每一部分。这种方法要比任何其它类型的分析(例如XML DOM分析方法)快得多。
这正是为什么Mabon实现JSON的原因―你能够控制响应,而且JSON具有语法简单和分析速度快的特点。
(八)encodeEnd()方法
真正的工作是在encodeEnd()方法中完成的,见列表7。在encodeEnd()方法中,我们从HtmlInputSuggest组件得到属性的Map。这个组件的属性之一是doSuggest属性。通过这个属性,我们能够得到MethodBinding(如果有的话),并且从这个MethodBinding对象,我们能够得到实际的由Web开发者所定义的MethodBinding表达式(例如,#{backingBean.doSuggest})。然后,我们从表达式中修整#{}并且用类似mabon:/协议的语法来连接字符串的余下部分。最后,MabonViewHandler将识别这个字符串并返回一个资源URL―它将被写向客户端(例如,/context-root/mabon-servlet-mapping/backingBean.doSuggest)。
三、使用输入建议组件
创建一套AJAX方案并不是一项简单的任务,尽管有若干使得这类工作更为容易些的AJAX工具包可用(例如Dojo Toolkit,www.dojotoolkit.org)。相比之下,JSF提供的是一种更为简单的编程模型和一种为大量开发者所熟悉的工具:JSP和Java。为了完整地结束本文中所提供的Ajax解决方案,让我们分析一下你如何在一个JSF应用程序中使用这个输入建议组件,由列表8所示。
这个页面包含一个HtmlInputSuggest组件(
value属性仅是一个普通的JavaBean属性。但是,显示于列表10中的doSuggest()方法却值得引起你的注意。这个方法使用由用户输入的初始值,该值是从doChange()函数(见列表3)中经由Mabon传递给它的。然后,doSuggest()方法根据用户在客户端输入的初始值返回一个经过过滤的数组。值得注意的是,返回的值遵循支持的JSON语法。
这个HtmlInputSuggest组件的最后结果显示于图2中。
图2.在一个浏览器中生成HtmlInputSuggest组件
四、结论
从本文中,我们希望你已经理解了如何使用Mabon来实现你的JSF组件以支持基于Ajax技术的数据回取,以及怎样通过利用Weblets工程把你的JSF组件需要的外部资源打包到与你的Java类相同的文档中。
最后,既然你已经知道怎样利用JSF和AJAX技术创建可重用的丰富互联网应用程序,那么我们非常希望你能够利用你在本系列文章中所学的技术来创建自己的定制组件以构建丰富互联网应用程序(RIA)。
推荐:系列文章《基于AJAX和JSF打造丰富的互联网组件》前三篇
第二篇:基于AJAX和JSF打造丰富的互联网组件之Weblets篇
第三篇:基于AJAX和JSF打造丰富的互联网组件之Mabon篇
(责任编辑:铭铭 mingming_ky@126.com TEL:(010)68476606)






