带转换器的复合 JSF 组件

Composite JSF component with converter

我有一个复合 JSF 组件 TimePicker.xhtml 和一个支持组件 timePickerComponent,其用法如下:

      <mi:timePicker style="display: initial;"
        widgetVar="toTimepickerWidget"
        converter="#{timePickerConverter}"
                            value="#{calendarBean.event.to}" 
      /> 

timePickerConverter 以通常方式创建:

public class TimePickerConverter implements Converter, Serializable {
    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2)
            throws ConverterException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)
            throws ConverterException {
        // TODO Auto-generated method stub
        return null;
    }
}

如何在复合组件中使用此转换器?

更新:

这是复合组件的代码:

<cc:implementation componentType="timePickerComponent">
    <h:outputScript name="js/timepicker/timepicker_helper.js" target="head"/>
    <div id="#{cc.clientId}" style="#{cc.attrs.style}">

            <p:inputText id="timepicker"
                    scrollHeight="200"
                    value="#{cc.timeLocal}"  
                    size="5"/>

    </div>
</cc:implementation>

基本上我想要的是将纯文本从 inputText 转换为 Date 对象。日期部分与我无关,我只需要对象的时间部分。 顺便说一句,作为临时解决方案,我将使用 getConvertedValue,如 BalusC Composite component with multiple input fields 这篇文章中所述,但我想知道如何将此功能委托给外部转换器也是如此,如文章

中所述

Normally this method is not to be overridden and everything is delegated to default JSF Converter mechanisms

为了使用转换器,您可以在支持组件中的方法 getConvertedValue 中显式调用转换器。可以从组件的 converter 属性中检索转换器:

@FacesComponent("timePickerComponent")
public class TimePickerComponent extends UIInput implements NamingContainer {

    ...

    @Override
    public Object getSubmittedValue() {
        UIInput hourComp = (UIInput) findComponent("timepicker_hour");
        UIInput minutesComp = (UIInput) findComponent("timepicker_minutes");
        return hourComp.getSubmittedValue() + ":" + minutesComp.getSubmittedValue();
    }

    @Override
    protected Object getConvertedValue(FacesContext context,
            Object newSubmittedValue) throws ConverterException {
        Converter converter = (Converter) getAttributes().get("converter");
        if (converter != null) {
            return converter.getAsObject(context, this, (String) newSubmittedValue);
        } else {
            return newSubmittedValue;
        }
    }

}

查看示例代码: https://github.com/destin/SO-answers/tree/master/SO-composite-jsf-component-with-converter

但是,这种方法的缺点是 JSF 组件从 String 转换而来。据我了解,您的组件由几个子元素组成。它们的所有值都需要转换为字符串(就像我所做的那样:hourComp.getSubmittedValue() + ":" + minutesComp.getSubmittedValue())。

因此,如果 TimeConverters 独立于 JSF 组件,您可能更愿意定义自己的层次结构。这样的转换器将能够使用很少的参数或一些复杂的对象(如 Time)作为源。可以用与我完全相同的方式检索此类转换器。