我有一個<ui:repeat>
標記的奇怪問題。即使對於我非常簡單的例子,嵌套重複組件內的值綁定也不能按預期工作。JSF:嵌套UI中的值綁定:重複
我有一個簡單的facelet像這樣:
<h:body>
<h:form>
<ui:repeat value="#{sandbox.rows}" var="row">
<ui:repeat value="#{row.columns}" var="column">
<h:outputText value="#{column.value}" />
<h:selectBooleanCheckbox value="#{column.value}" />
</ui:repeat>
<br/>
</ui:repeat>
<h:commandButton action="#{sandbox.refresh}" value="Refresh" />
</h:form>
</h:body>
和沙盒類:
@Component
@Scope("request")
public class Sandbox {
public static class Row {
private List<Column> columns = Arrays.asList(new Column(), new Column());
public List<Column> getColumns() {
return columns;
}
}
public static class Column {
private boolean value;
public void setValue(boolean value) {
this.value = value;
}
public boolean getValue() {
return this.value;
}
}
public List<Row> rows = Arrays.asList(new Row(), new Row());
public List<Row> getRows() {
return rows;
}
public void refresh() {
rows.get(0).getColumns().get(0).setValue(true);
System.err.println("refresh clicked");
}
}
所以我的facelet遍歷在沙箱中「行」,其中有一個數字「列「,每個都有價值。對於每個這樣的列,將打印該值,並輸出與其綁定的值的<h:selectBooleanCheckbox>
。
當我加載頁面時,所有值都顯示爲false,並且所有複選框都未選中。現在,單擊刷新應該將第一行的第一列的值更改爲true。不過,我得到以下輸出:
true [ ] false [ ] false [ ] false [ ]
換句話說,在<h:outputText>
顯示其爲真,但複選框不檢查。我當然可以在調用應用程序階段更改模型,並且在渲染視圖時應該反映這一點。
如果我刪除一層嵌套,所以只有一個<ui:repeat>
,一切都按預期工作:複選框被選中並且值顯示爲true。所以這似乎與UIRepeat組件有關。事實上,似乎UIRepeat在嵌入另一個UIRepeat時有特殊的處理。
從我收集的內容來看,UIRepeat從本質上重新渲染了相同的組件。在每次渲染調用之間,它會從內部映射(鍵入渲染組件的實際ID)中加載實現EditableValueHolder
的所有子組件的「狀態」(value,localValue,submittedValue)。我嘗試過在發生這種情況時要將斷點插入保存狀態的地圖中,但這確實是一團糟,因爲saveChildState和restoreChildState方法被調用了大量的時間。
任何想法?我可以採取不同的方式嗎?我真正需要的是能夠渲染一個可以水平和垂直動態增長的表格,包含複選框,輸入字段等。我瞥了一眼<h:dataTable>
,但我相信在這種情況下它不起作用。
我的外層循環不能是c:forEach,因爲在我的真實應用程序中,它全部嵌入到複合組件中。 – waxwing 2010-09-14 18:07:15
再一次,我很驚訝你的知識和樂於助人。謝謝!我會熱切追蹤這個問題,看看他們說了些什麼。 – waxwing 2010-09-14 18:08:43
不過,它*可以*。你有什麼問題?編輯:沒問題,不客氣。 – BalusC 2010-09-14 18:08:53