【问题标题】:JSF UIInput in DataTable Footer数据表页脚中的 JSF UIInput
【发布时间】:2009-06-11 15:25:45
【问题描述】:

我将 (UIInput) 添加到动态创建的数据表 (UIData) 的页脚列 (UIColumn) 中。 UIData 绑定到 jsp 中的数据表标签。 在数据表中,我只有页眉和页脚,页眉的标签和页脚在可编辑的文本框中具有相应的值。 当我更改值并使用命令按钮提交表单并尝试在操作方法中使用 .getValue() 访问 UIInput 值时,我只获取旧值而不是页面中更新的值。 我尝试将它绑定到支持 bean 中的属性并检查设置器中设置的值。我注意到正在设置旧值,而我在页面中更新的值并未反映在操作方法或设置器中。 我尝试使用 .getValue、.getLocalValue、.getSubmittedValue。这些都没有给我新的价值观。 有什么建议我可能会做什么?


我设法通过从 requestParameterMap 中提取值来解决问题。 如果有解决该问题的方法,请告诉我。 McDowell - 感谢您的投入。

【问题讨论】:

  • 您能否提供一个非常简单的页面和 bean 来重现该问题?这将有助于缩小问题范围。

标签: jsf datatable textinput


【解决方案1】:

我尝试在 Tomcat 上的 MyFaces 1.2.3 和 Glassfish 上的 Mojarra 2.0.0 Beta 下运行 your demo code 代码,但无法重现该问题 - save() 方法打印了我在字段中输入的值。

(要使用 MyFaces,我必须将 new UIData() 更改为 new HtmlDataTable(),这可能是由于他们如何实现表格渲染器,但这是一个小改动。)

我会注意一些关于 bean 的事情:

  • 每次调用 table getter 时都会不断添加列 - 就像使用服务器端状态保存刷新页面时一样
  • 在会话 bean 中保留对 UIComponent 的引用通常不是一个好主意;您最好使用请求范围进行组件绑定
    • 会话 bean 应该实现 Serializable(虽然我意识到不是每个人都这样做)并且 UIComponents 不能被序列化
    • 如果用户打开页面两次,您的组件可能会出现在多个视图中 - 并发问题
    • 根据spec:JSF创建视图时,会使用通过getter绑定的组件;但是,当它恢复视图(提交时)时,它将通过设置器设置组件,因此保留引用(充其量)是多余的

您可能希望将 getter 更改为以下内容:

private UIData headerDataTable;

public UIData getHeaderDataTable() {
    if (headerDataTable == null) {
        headerDataTable = new UIData();
        getHeaderTable(headerDataTable);
    }
    return headerDataTable;
}

我不相信这些更改会解决您的问题,但是 - 如果您仍然遇到问题,请再试一次并提供更多详细信息 - 您的 JSF 实现、版本和 javax.faces.STATE_SAVING_METHOD 的值 web.xml 中的 em> 参数(如果有)。

【讨论】:

    【解决方案2】:

    实际代码做了几个其他处理,但下面的代码应该有助于复制问题。在下面的代码中,我希望 TestString 从页面输出修改后的值。但它只是返回旧值。 下面是jsp:

    <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
    <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
    <html>
    <head>
    </head>
    <f:view>
        <body>
            <h:form styleClass="form" id="form1">
                <h:commandButton value="Save" action="#{TestPageBackingBean.save}"  styleClass="commandExButton"/>
                <h:outputText styleClass="label" value="Header Table"/>
                <h:dataTable binding="#{TestPageBackingBean.headerDataTable}"></h:dataTable>
            </h:form>
        </body>
    </f:view>
    </html>
    

    下面是人脸配置:

    <managed-bean>
        <managed-bean-name>TestPageBackingBean</managed-bean-name>
        <managed-bean-class>test.jsf.TestPageBackingBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean> 
    

    下面是后台bean代码:

    package test.jsf;
    
    import java.io.IOException;
    
    import javax.faces.component.UIColumn;
    import javax.faces.component.UIData;
    import javax.faces.component.UIInput;
    import javax.faces.component.UIOutput;
    import javax.faces.context.FacesContext;
    
    public class TestPageBackingBean {
    
      private UIData headerDataTable = new UIData();
    
      public TestPageBackingBean() {
    
      }
    
      public UIData getHeaderDataTable()
        {    
                return getHeaderTable(headerDataTable);
        }       
    
      public UIData getHeaderTable(UIData dataTable)
        {    
            for (int i=0;i<10;++i)
            {
                dataTable.getChildren().add(getColumn(i));
            }
            return dataTable;
        }
    
        private UIColumn getColumn(int i)
      {
        UIOutput outputLabelText = new UIOutput();
            UIInput inputFieldText = new UIInput(); 
            UIColumn column = new UIColumn();
    
            outputLabelText.setValue("Label" + i);
            inputFieldText.setValue("test input" + i);
    
            column.setHeader(outputLabelText);
            column.setFooter(inputFieldText);
            return column;
        }
    
        public String save() throws IOException {
                String TestString = "";
                FacesContext ctx = FacesContext.getCurrentInstance();
                if (!ctx.getResponseComplete()) {
                    for (int i=0; i<headerDataTable.getChildren().size();++i)
                    {
                        TestString = TestString + (String)((UIInput)((UIColumn) headerDataTable.getChildren().get(i)).getFooter()).getValue();
                    }
                 System.out.println(TestString);
                }
               return "save";
            }
    
        public void setHeaderDataTable(UIData headerDataTable) {
            this.headerDataTable = headerDataTable;
        }   
    }
    

    【讨论】:

      【解决方案3】:

      问题尚未完全解决。

      我使用 RSA 7,IBM JSF - Base Faces Support 7.0 and Enhanced Faces Components 7.0 on WAS 6.0 javax.faces.STATE_SAVING_METHOD 默认为“服务器”。

      我尝试将 STATE_SAVING_METHOD 更改为“客户端”。它确实在输出中打印了更改的值,但在 label4 而不是我修改的 label0 中打印。在下一次提交时,值从 label4 移动到 label8。似乎不一致。

      【讨论】:

        猜你喜欢
        • 2010-10-19
        • 1970-01-01
        • 1970-01-01
        • 2014-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-06
        相关资源
        最近更新 更多