联合使用Dynamic Faces和jMaki
至此,我们已经学习了如何使用Dynamic Faces重新显示支持Ajax的JavaServer Faces组件。但是,如何增添曾经在基于JavaServer Faces的应用软件中看到的支持Ajax的widget呢?
我们可以利用Project jMaki将喜欢的widget封装在JavaServer Faces组件中。这样,我们既能够享受到JavaServer Faces组件模式的好处,也能够获得使用被封装为JavaServer Faces组件的widget的灵活性。 同时,我们无须编写为现有组件实现Ajax功能的javascript代码,以及为widget创建JavaServer Faces组件所要求的Java平台代码。
如何联合使用jMaki和Dynamic Faces呢?对于网页创作者而言,这非常简单,就是将与jMaki widget相关的标签拖到网页中。
为了联合使用jMaki widget和Dynamic Faces,widget开发人员需要对jMaki widget的组件文件作一些小小的修改。这些修改使jMaki widget能够充分利用JavaServer Faces技术提供的组件状态管理系统,正确地转换Dynamic Faces要求的header。修改的细节超出了三篇文章的讨论范围,读者可以参阅相关资料。
Dynamic Faces开发团队已经完成了转换3个与Dynamic Faces.联合使用的jMaki widget所需要的工作。被转换的jMaki widget是script.aculo.us in-place editor widget、Dojo fisheye widget、Dojo inline-editor widget。
除了转换fisheye widget,开发团队还修改了jMaki API,使widget能够触发一个JavaServer Faces价值修改事件,如下图所示:
<a:ajax name="dojo.fisheye"
value="#{fishEyeBean.selectedIndex}"
valueChangeListener="#{fishEyeBean.valueChanged}"
args="{items:[
{iconSrc:'images/150x126_jalopy.jpg',caption:'Jalopy',index:0},
{iconSrc:'images/150x126_luxury.jpg',caption:'Luxury',index:1},
{iconSrc:'images/150x126_roadster.jpg',caption:'Roadster',index:2},
{iconSrc:'images/150x126_suv.jpg',caption:'SUV',index:3}
]}"
/>
Dynamic Faces和jMaki开发团队正在加紧工作,确保所有的jMaki widgets支持Dynamic Faces。
现在,让我们来站在网页创作者的角度来讨论这一问题。要想搞明白如何联合使用jMaki script.aculo.us in-place editor widget和 Dynamic Faces,我们在一个JavaServer Faces数据表组件中包含该widget,使我们能够编辑该表中一个单元的值。
在JSP网页中,我们必须说明要求的标签库,以及Dynamic Faces和jMaki标签,如下所示:
<%@taglib prefix="f"
uri="http://Java.sun.com/jsf/core"%>
<%@taglib prefix="h"
uri="http://Java.sun.com/jsf/html"%>
<%@taglib prefix="jsfExt"
uri="http://Java.sun.com/jsf/extensions/dynafaces"%>
<%@taglib prefix="a"
uri="http://Java.sun.com/jmaki-jsf" %>
下面的代码添加的是<jsfExt:scripts />标签:
<f:view>
<html>
<head>
<title>Table with jMaki</title>
<jsfExt:scripts />
</head>
<body>
这一标签显示Dynamic Faces所要求的JavaScript文件的<script>元素。
最后,通过包含一个指定被封装为jMaki widget 的in-place editor的 jMaki ajax标签,我们就将该widget添加到了网页上。
<h:form>
<h:dataTable
...
rows="10" binding="#{ResultSetBean.data}"
value="#{ResultSetBean.list}"
var="customer">
<h:column>
<f:facet name="header">
<h:outputText value="Account Id"/>
</f:facet>
<h:outputText id="accountId"
value="#{customer.accountId}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Customer Name"/>
</f:facet>
<a:ajax name="scriptaculous.inplace"
value="#{customer.name}"/>
</h:column>
</h:dataTable>
...
</h:form>
</body>
</html>
</f:view>
需要注意的是,当用户点击Customer Name列中的一个元素时,客户名字元素会被一个输入组件、一个"OK"按钮、一个"Cancel"链接所取代,使用户能够编辑当前的客户名字。如果用户点击"Cancel"而不是"OK",该单元就会被重新显示为原来的值;如果用户输入一个值,并点击"OK"按钮,新的值就会被利用Ajax技术发送到服务器,使该模式更新为新的值。 然后,被编辑的单元就会被重新显示。 图5显示的是是单元被修改后的网页:

图5:在用户向服务器提交新的值后,网页重新显示为新的值
结论
Project Dynamic Faces向我们提供了一种向基于JavaServer Faces的应用软件中添加Ajax功能的灵活、有效的方式,而无需放弃JavaServer Faces组件模式的任何优势。在内置的javascript库、Ajax实现、Dynamic Faces提供的组件交互模式的帮助下,我们会发现利用Dynamic Faces添加Ajax功能更容易了。基于JavaServer Faces的应用软件能够得益于jMaki widget提供的更多的灵活性。