在 JSF 2 简介 系列的 上一期 中,我讨论了使用内置的 Ajax 实现自动完 成复合组件。页面作者可以在一个 facelet 中使用该组件,该组件负责处理所 有 Ajax 细节。尽管内置的 Ajax 已经存在,但仍然可以在开发人员实现复合组 件之后(可能是很长一段时间以后),方便地让页面作者将 Ajax 添加到该组件 中。本文将展示复合组件如何容纳后来添加的 Ajax。
在 “JSF 2 简介,第 3 部分:事件处理、JavaScript 和 Ajax” 中已经讨 论过,JSF 2 的 <f:ajax> 标记允许页面作者将后来的 Ajax 添加到 JSF 2 的内置组件中。例如,使用 <f:ajax>,您可以轻松将一个提交按钮转 变为一个 Ajax 按钮:
<h:commandButton value="Click me">
<f:ajax>
</h:commandButton>
但是, JSF 2 的 <f:ajax> 标记不会处理复合组件(确实如此),因 为复合组件只是组件容器。
例如,在 “JSF 2 简介,第 2 部分:模板及复合组件” 中,我介绍了一个 简单的图标复合组件,它包含一个链接,由一幅图像表示。当用户单击该图标时 ,该链接提交一个表单,后者触发一个与图标链接相关联的服务器端动作侦听器 。使用图标很简单:
<util:icon image="...">
<f:actionListener for="link" type="...">
</util:icon>
因为您可以使用 <f:ajax> 标记将提交按钮转变为 Ajax 按钮,您可 能认为您能够对图标执行相同操作:
<util:icon image="...">
<f:ajax>
<f:actionListener for="link" type="...">
</util:icon>
上面的代码片段不会生效,因为我向图标组件附加了 <f:ajax> 标记 ,我真正想要做的是将它附加到图标内部的链接上。
在本例中,我需要的是一种允许我将 Ajax 行为附加到图标内部的链接的机 制,或者更一般地,允许我将 Ajax 行为附加到复合组件内部的组件。这种机制 (在 Mojarra 和 Apache MyFaces 中实现过,而在 JSF 2.0 中完全没有记录) 是本文讨论的重点。(注意:在编写本文时已添加了 MyFaces 支持。)在了解 该机制的工作原理之前,我将创建一个新的图标复合组件供使用。
可重用的图标组件
想象一下您拥有一项全世界最酷的工作。也许您正在实现新一代魔兽世界图 形引擎。但遗憾的是,这只是个梦想。今天,您要实现的是如图 1 所示的字体 选择程序:
图 1. 选择一种字体