jsf2.0:基于java的定制组件&x2B;html表格+;facelets=数据模型未更新

jsf2.0:基于java的定制组件&x2B;html表格+;facelets=数据模型未更新,jsf,glassfish,facelets,custom-component,jsf-2,Jsf,Glassfish,Facelets,Custom Component,Jsf 2,我在通过JSF2.0和Facelets正确更新HtmlDataTable的数据模型时遇到问题 我创建了一个自定义的基于Java的组件,该组件扩展了HtmlDataTable,并在EncodeBeagin方法中动态添加了列 @Override public void encodeBegin(FacesContext context) throws IOException { if (this.findComponent("c0") == null) { for (int i = 0

我在通过JSF2.0和Facelets正确更新HtmlDataTable的数据模型时遇到问题

我创建了一个自定义的基于Java的组件,该组件扩展了HtmlDataTable,并在EncodeBeagin方法中动态添加了列

@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);
}
调用时,页面正确呈现为一个由3列(在运行时添加)和2行(因为我的数据模型有2行)组成的表。但是,当用户在输入字段中输入一些数据,然后单击submit按钮时,模型没有正确更新,因此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>
我更新测试页面如下

@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完成的


谢谢您的帮助。

您的问题可能在这里:

myNewText.setValue("#{row[" + i + "]}");
您在这里设置的是字符串值,而不是值绑定。您需要执行以下操作:

Application application = facesContext.getApplication();
ExpressionFactory expressionFactory = application
        .getExpressionFactory();
...
ValueExpression valueExpression = expressionFactory
            .createValueExpression(facesContext.getELContext(),
                    "#{row[" + i + "]}", String.class);
myNewText.setValueExpression("value", valueExpression );

它演示了JSF 2.0的编程用法。

您的问题可能在这里:

myNewText.setValue("#{row[" + i + "]}");
您在这里设置的是字符串值,而不是值绑定。您需要执行以下操作:

Application application = facesContext.getApplication();
ExpressionFactory expressionFactory = application
        .getExpressionFactory();
...
ValueExpression valueExpression = expressionFactory
            .createValueExpression(facesContext.getELContext(),
                    "#{row[" + i + "]}", String.class);
myNewText.setValueExpression("value", valueExpression );

它演示了JSF 2.0的编程用法。

您好,感谢您的建议,但是使用setValueExpression而不是setValue方法并没有解决问题。提交表格时,数据模型不会更新。还有其他建议吗?这是一个复杂的设置,很多事情可能会出错。我指出的无论如何都是个问题。尝试跟踪/调试,在输入文本控件呈现程序的decode methode中设置断点,然后从那里开始跟踪。您好,感谢您的建议,但是使用setValueExpression而不是setValue方法并不能解决问题。提交表格时,数据模型不会更新。还有其他建议吗?这是一个复杂的设置,很多事情可能会出错。我指出的无论如何都是个问题。尝试跟踪/调试,在输入文本控件呈现器的decode methode中设置断点,然后从那里开始跟踪。