原则与技巧
开发 JSF 自定义复合组件主要有两个原则,一方面强调重用已有的标准组件;另一方面如何确保自定义组件易于重用。
1.尽可能的重用标准组件的功能和实现
传统的自定义复合组件开发建议完全覆盖实现 encode/decode 逻辑,但这样做耗费时间而且容易出错。毫无疑问,我们可以通过重用标准组件的渲染器等机制减少甚至根本不用自行编写这部分代码。另外,为了实现灵活的配置和使用,自定义复合组件通常需要提供很多属性,我们需要写很多代码来处理这些属性的读写和状态管理。实际上,我们可以简单地把自定义复合组件的属性传递给它自身包含的标准组件,由已有的标准代码去处理这些属性,而不用重复写这些代码。
2.清晰地分离组件类、标签类和模型类
JSF 的组件模型建议在组件类、标签类和模型类之间有明确清晰的责任分配,以便于重用和扩展。组件类不应该依赖于 javax.faces.component.html 包,因为组件类不仅可以用于 HTML,而且还应该可以重用于其它标记语言(如 WML)。也就是说组件类不应该直接引用 javax.faces.component.html 包内的 HTML 组件。例如,在你的组件类中创建一个 HtmlCommandButton 的实例是不可取的,你应该考虑用 javax.faces.component 包中的 UICommand 。另一方面,如果你希望你的模型类可以重用于不同的 Web 框架,那么你的模型类就不应该依赖于 JSF 的任何包,即模型类只表示业务对象而不包含任何用户界面相关的组件、数据和状态。
基于这些原则,对比传统方式和本文介绍的技巧,我们可以发现基于重用的开发策略会极大简化 JSF 自定义复合组件的编写。开发 JSF 自定义组件通常需要如下 3 个步骤(参考“怀疑论者的 JSF: JSF 组件开发”)。
1.扩展 UIComponent
·传统方式:创建一个类,扩展 UIComponent,保存组件状态,在 faces-config.xml 中注册组件
重用技巧:
·选择 UIPanel 作为布局容器,重用标准组件作为复合组件的子组件。
·实现内部动作监听器。
2.定义渲染器或者内联实现它
传统方式:覆盖实现 encode/decode,在 faces-config.xml 中注册渲染器。
重用技巧:重用标准渲染器类型。
3.创建自定义标签,继承 UIComponentTag
传统方式:返回渲染器类型和组件类型,设置 JSF 表达式属性
重用技巧:传递属性值给作为子组件的标准组件。