JSF无法在h:dataTable中解析来自支持bean的转换器ID

时间:2010-12-07 19:25:47

标签: java jsf facelets converter

我在JSF中有一个动态数据表,它有多个输入元素,可以是各种数据类型。输入始终是文本控件,但可以包含数字或文本数据。为了解决这个问题,每个字段都从辅助bean中检索它的converterId:

<h:dataTable id="indexFieldTable" value="#{indexFieldBean.indexField}" var="item">
  <h:column id="column">

    <h:inputText id="inputID" value="#{item.value}">
      <f:converter id="ifConverter" converterId="#{item.converter}" />
      <f:validator id="ifValidator" validatorId="#{item.validator}" />
    </h:inputText>
  </h:column>
</h:dataTable>

但是,渲染时,我收到此错误:Expression Error: Named Object: ' not found.

如果我将converterId硬编码为已知值,则可以正常工作:

<f:converter id="ifConverter" converterId="stringConverter" />

如何动态配置converterId?

1 个答案:

答案 0 :(得分:3)

f:标记特定于组件,而不是迭代项。在视图构建时(当组件在视图的组件树中填充时),#{item}不可用。它仅在渲染时间内可用。您确实需要将它们的值附加到父bean,而不是迭代项。

要解决此问题,请首先更改Field类(由#{item}表示)以获得完整的ConverterValidator属性(您可以在Field创建它们{1}}的结构)。

public class Field {
    private Converter converter;
    private Validator validator;

    // ...
}

然后更改bean以在DataModel中包装这些字段的集合,并具有通用的转换/验证方法,这些方法委派给DataModel中当前迭代的项目DataModel#getRowData() }:

public class Bean {
    private List<Field> fields;
    private DataModel<Field> fieldModel;

    public Bean() {
        fields = loadItSomehow();
        fieldModel = new ListDataModel<Field>(fields);
    }

    public Converter getFieldConverter() {
        return fieldModel.getRowData().getConverter();
    }

    public void validateField(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        fieldModel.getRowData().getValidator().validate(context, component, value);
    }

    // ...
}

最后更改视图中的输入字段,如下所示,将h:dataTable的值绑定到DataModel,将转换器/验证器绑定到父bean的值,后者又将调用委托给目前已迭代的项目:

<h:dataTable value="#{bean.fieldModel}" var="field">
    <h:column>
        <h:inputText value="#{field.value}" converter="#{bean.fieldConverter}" validator="#{bean.validateField}" />
        ...

需要注意的是,这种复杂性并不是由于JSF的性质,而是由于您具有非常具体的功能要求。通常,h:dataTable用于表示tabluar数据,而不是用于生成动态表单。