2010-12-07 66 views
1

在JSF中有一個動態數據表,它具有多個可以是各種數據類型的輸入元素。輸入始終是一個文本控件,但可以包含數字或文本數據。爲了解決這個問題,每個字段從後臺bean檢索其converterId:JSF無法從h:dataTable中的backing bean解析Converter ID

<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?

+0

你確定`item.converter`不是空的嗎? – Bozho 2010-12-07 19:39:17

+0

我很積極。我添加了以確保正確的值出現。 – Travis 2010-12-07 19:42:25

回答

3

f:標籤特定於組件,而不是迭代項目。在視圖構建時(當組件在視圖的組件樹中填充時),#{item}不可用。它只在渲染時間內可用。你真的需要將它們的值附加到父bean,而不是迭代項。

爲了解決這個問題,首先改變Field類(由#{item}表示)有fullworthy ConverterValidator屬性(你可以只是在Field的建設創建它們)。

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

    // ... 
} 

然後改變豆包裹這些領域的集合中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將用於表示製表數據,而不是生成動態表單。