|
Component可以自己负责将对象数据编码为HTML文件或其它的输出文件,也可以将这个任务委托给 Renderer,这边先介绍的是让Component自己负责编码的动作。 这边着重的是介绍完成自订组件所必须的流程,所以我们不设计太复杂的组件,这边将完成以下的组件,这个组件会有一个输入文字栏位以及一个送出按钮: ![]() 您要继承UIComponent或其子类来自订Component,由于文字栏位是一个输入栏位,为了方便,您可以继承UIInput类,这可以让您 省去一些处理细节的功夫,在继承UIComponent或其子类后,与编码相关的主要有三个方法:
其中encodeChildren()是在包括子组件时必须定义,Component如果它的 getRendersChildren()方法传回true时会调用encodeChildren()方法,默认上, getRendersChildren()方法传回false。 由于我们的自订组件相当简单,所以将编码的动作写在encodeBegin()或是encodeEnd()都可以,我们这边是定义encodeBegin ()方法:
package onlyfun.caterpillar; 在encodeBegin()方法中,我们取得ResponseWriter对象,这个对象可以协助您输出HTML标签、属性等,我们使用 getClientId()取得组件的id,这个id是每个组件的唯一识别,默认上如果您没有指定,则JSF会自动为您产生id值。 接着我们分别对输入文字栏位及送出钮作HTML标签输出,在输出时,我们将name属性设成clientId与一个字符串值的结合(即TEXT或CMD),这是为了方便在解码时,取得对应name属性的请求值。 在encodeTextField中我们有调用getValue()方法,这个方法是从UIOutput继承下来的,getValue() 方法可以取得Component的设定值,这个值可能是静态的属性设定值,也可能是JSF Expression的绑定值,默认会先从组件的属性设定值开始找寻,如果找不到,再从绑定值(ValueBinding对象)中找寻,组件的属性值或绑 定值的设定,是在定义Tag时要作的事。 编碥的部份总结来说,是取得Component的值并作适当的HTML标签输出,再来我们看看解码的部份,这是定义在decode()方法中,将下面的内容加入至上面的类定义中: ....
public void decode(FacesContext context) { Map reqParaMap = context.getExternalContext(). getRequestParameterMap(); String clientId = getClientId(context); String submittedValue = (String) reqParaMap.get(clientId + TEXT); setSubmittedValue(submittedValue); setValid(true); } .... 我们必须先取得RequestParameterMap,这个Map对象中填入了所有客户端传来的请求参数, Component在这个方法中有机会查询这些请求参数中,是否有自己所想要取得的数据,记得我们之前解码时,是将输入栏位的name属性解码为 client id加上一个字符串值(即TEXT设定的值),所以这时,我们尝试从RequestParameterMap中取得这个请求值。 取得请求值之后,您可以将数据藉由setSumittedValue()设定给绑定的bean,最后调用setValid()方法,这个方法设定为 true时,表示组件正确的获得自己的值,没有任何的错误发生。 由于我们先不使用Renderer,所以在构造函数中,我们设定RendererType为null,表示我们不使用Renderer进行解码输出: public UITextWithCmd() {
setRendererType(null); } 在我们的例子中,我们都是处理字符串对象,所以这边不需要转换器,如果您需要使用转换器,可以调用setConverter()方法加以设定,在不使用 Renderer的时候,Component要设定转换器来自行进行字符串与对象的转换。 |