2011-10-07 29 views
4

我存儲值表達式的JSF組件與F的「ValueExpression地圖」:屬性標記,例如:JSF組件

<h:inputText ...> 
    <f:attribute name="myId1" value="#{bean.prop1}" /> 
    <f:attribute name="myId2" value="#{bean.prop2}" /> 
    <f:attribute name="myId3" value="#{bean.prop3}" /> 
</h:inputText> 

有沒有以編程方式訪問所有這些值表達式的方法嗎? (不知道名稱myId1,myId2,...)

JSF 2.1規範的第9.4.2節說,這些值存儲在「組件的ValueExpression映射表」中。 這是整個規範中唯一出現的術語「ValueExpression Map」。 如何訪問該地圖?

在UIComponent的方法getValueExpression()中的的Jboss /鑽嘴魚科執行地圖

getStateHelper().get(UIComponentBase.PropertyKeys.bindings) 

的用於獲得一個單一值表達式。

我猜那個地圖是「ValueExpression Map」的超集? 我可以確定所有實現和所有繼承(標準)組件都使用該映射來存儲ValueExpressions嗎?

謝謝。

回答

2

理論你應該能夠通過UIComponent#getAttributes()一飽眼福:

Map<String, Object> attributes = component.getAttributes(); 

for (Map.Entry<String, Object> entry : attributes.entrySet()) { 
    System.out.printf("name=%s, value=%s%n", entry.getKey(), entry.getValue()); 
} 

但是,不工作,你所希望的方式。它只返回靜態屬性。這似乎不會被固定/實施。另見JSF issue 636。我建議堅持使用預先定義的前綴和增量數字後綴的屬性,就像您在示例中介紹的那樣。這也是我一直用來從組件傳遞額外信息到自定義驗證器和轉換器的原因。你可以只收集它們如下:

Map<String, Object> attributes = component.getAttributes(); 
List<Object> values = new ArrayList<Object>(); 

for (int i = 1; i < Integer.MAX_VALUE; i++) { 
    Object value = attributes.get("myId" + i); 
    if (value == null) break; 
    values.add(value); 
} 

System.out.println(values); 
+0

我不認爲該規範允許在屬性映射中存儲像上面那樣的f:屬性值。 Mojarra沒有。 你上面測試了你的代碼嗎?你正在使用哪個實現? – Thomas

+0

咦?爲什麼你這麼想?所有組件的屬性都在那裏,參見鏈接的javadoc:*「返回一個表示與此UIComponent關聯的屬性(和屬性,見下文)的可變Map,由屬性名稱(必須是String)鍵入」*「。這從JSF 1.0開始就是這樣工作的。 – BalusC

+0

9.4.2的規範說:「...對參數值調用isLiteralText()方法,如果返回true,則將該值存儲在上面派生的名稱下的組件屬性Map中;如果返回false,則存儲在上面派生的名稱下的組件的ValueExpression Map中的ValueExpression。「 此外,我已經testet它和屬性映射不包含它們。 – Thomas

1

BalusC給出的可能是使用嵌套面或UIParameter組件答案的替代品。方面可以使用getFacets作爲地圖檢索,但您可能需要在每個方面內部放置額外的UIOutput以訪問其值表達式。

嵌套UIParameters可以通過遍歷子組件和檢查instanceof UIParameter來訪問。 UIParameters具有namevalue屬性,因此可以輕鬆轉換爲地圖。

我在自定義組件中使用了參數,但我不確定標準UIInput如何在您的示例中對這些參數做出反應。

0

BalusC是對的。 UIComponent#getAttributes()。get(name)從兩個地方獲取值 - 首先從屬性映射中獲取值,然後從「值表達式映射」中找到。爲了增加一些價值,你必須調用UIComponent#setValueExpression(name,ValueExpression)。如果值是字面值,則將其存儲到屬性映射中,否則將存儲到「值表達式映射」中。一切都很好。