У меня возникают проблемы с корректным обновлением модели данных HtmlDataTable с помощью JSF 2.0 и Facelets.
Я создал пользовательский компонент на основе Java, который расширяет HtmlDataTable и динамически добавляет столбцы в методе encodeBegin.
@Override
public void encodeBegin(FacesContext context) throws IOException
{
if (this.findComponent("c0") == null)
{
for (int i = 0; i < 3; i++)
{
HtmlColumn myNewCol = new HtmlColumn();
myNewCol.setId("c" + i);
HtmlInputText myNewText = new HtmlInputText();
myNewText.setId("t" + i);
myNewText.setValue("#{row[" + i + "]}");
myNewCol.getChildren().add(myNewText);
this.getChildren().add(myNewCol);
}
}
super.encodeBegin(context);
}
Моя тестовая страница содержит следующее
<h:form id="fromtb">
<test:MatrixTest id="tb" var="row" value="#{MyManagedBean.model}">
</test:MatrixTest>
<h:commandButton id="btn" value="Set" action="#{MyManagedBean.mergeInput}"/>
</h:form>
<h:outputText id="mergedInput" value="#{MyManagedBean.mergedInput}"/>
Мой класс управляемых бинов содержит
@ManagedBean(name="MyManagedBean")
@SessionScoped
public class MyManagedBean
{
private List model = null;
private String mergedInput = null;
public MyManagedBean() {
model = new ArrayList();
List myFirst = new ArrayList();
myFirst.add("");
myFirst.add("");
myFirst.add("");
model.add(myFirst);
List mySecond = new ArrayList();
mySecond.add("");
mySecond.add("");
mySecond.add("");
model.add(mySecond);
}
public String mergeInput()
{
StringBuffer myMergedInput = new StringBuffer();
for (Object object : model)
{
myMergedInput.append(object);
}
setMergedInput(myMergedInput.toString());
return null;
}
public List getModel() {
return model;
}
public void setModel(List model) {
this.model = model;
}
public String getMergedInput() {
return mergedInput;
}
public void setMergedInput(String mergedInput) {
this.mergedInput = mergedInput;
}
При вызове страница корректно отображается с таблицей, состоящей из 3 столбцов (добавленных во время выполнения) и 2 строк (так как моя модель данных имеет 2 строки). Однако, когда пользователь вводит некоторые данные в поля ввода и затем нажимает кнопку отправки, модель обновляется неправильно, и поэтому метод mergeInput () создает последовательность пустых строк, которая отображается на той же странице.
Я добавил некоторые записи в метод decode () моего пользовательского компонента и вижу, что параметры, введенные пользователем, отправляются обратно вместе с запросом, однако эти параметры не используются для обновления данных. модель .
Если я обновлю метод encodeBegin () моего пользовательского компонента следующим образом
@Override
public void encodeBegin(FacesContext context) throws IOException
{
super.encodeBegin(context);
}
и я обновляю тестовую страницу следующим образом
<test:MatrixTest id="tb" var="row" value="#{MyManagedBean.model}">
<h:column id="c0"><h:inputText id="t0" value="#{row[0]}"/></h:column>
<h:column id="c1"><h:inputText id="t1" value="#{row[1]}"/></h:column>
<h:column id="c2"><h:inputText id="t2" value="#{row[2]}"/></h:column>
</test:MatrixTest>
страница отображается правильно, и на этот раз, когда пользователь вводит данные и отправляет форму, базовая модель данных корректно обновляется, а метод mergeInput () создает последовательность строк с пользовательскими данными.
Почему тестовый пример со столбцами, объявленными на странице Facelet, работает правильно (то есть модель данных корректно обновляется JSF), где этого не происходит, когда столбцы создаются во время выполнения с помощью метода encodeBegin ()
Есть ли какой-нибудь метод, который мне нужно вызывать или интерфейс, который мне нужно расширить, чтобы обеспечить корректное обновление модели данных?
Я использую этот тестовый пример для решения проблемы, возникающей в гораздо более сложном компоненте, поэтому я не могу достичь той же функциональности, используя составной компонент Facelet.
Обратите внимание, что это было сделано с использованием NetBeans 6.8, JRE 1.6.0u18, GlassFish 3.0.
Спасибо за вашу помощь.