向 p:datatable 中添加新行,然后提交内容。

4
我想在Primefaces数据表中添加一行,然后提交该表的内容并执行一些业务逻辑。数据表模型是在ViewScoped管理的bean中维护的集合。
我正在使用JSF 2.1和Primefaces 3.3。
简短示例:
    <h:form id="my-form">
        <p:dataTable value="#{testBean.list}" var="s" id="datatable">
            <p:column>
                <h:inputText value="#{s}"/>
            </p:column>
            <f:facet name="footer">
                <p:commandButton value="Add row" action="#{testBean.addRow()}" process="@form" update="@form" immediate="true" />
                <p:commandButton value="Do stuff" action="#{testBean.doSomeLogic()}" process="@form" update="@form"/>
            </f:facet>     
        </p:dataTable>
    </h:form>

托管 Bean:

@ManagedBean
@ViewScoped
public class TestBean implements Serializable {

private List<String> list;

public TestBean() {
}

@PostConstruct
public void init() {
    list = new ArrayList<String>();
    list.add("one");
    list.add("two");
}

public void addRow(){
    list.add(new String());
}

public void doSomeLogic(){
    for (String string : list) {
        System.out.println(string);
    }
}

// getters and setters

}

实际发生的情况:

  • 用户点击“添加行”按钮,会添加一行新数据(我需要立即执行以确保不进行验证,这些字段是较大表单的一部分)。
  • 用户点击“执行操作”,集合的大小正确(包括新行),但用户输入不被考虑在内(无论是对先前存在的行进行修改还是在新添加的行中添加新值)。

我该怎么做才能提交新值?我刚开始学习JSF,不确定是否已经完全理解。

谢谢您的帮助。

可能有重复问题:

编辑:问题已经得到解决,感谢Jitesh,可以在此处找到一个可行的示例:JSF2,我可以动态添加JSF组件吗?

2个回答

2
唯一的问题是您在inputText中使用了不可变对象。要了解这一点,请查看BaluC的答案
根据它的说法,“作为一个不可变对象,String没有setter方法。输入的值永远无法被设置。”
尝试从commandButton中删除immediate属性,您会发现在插入每一行时数据将被清除。

谢谢您指引我正确的方向,我移除了即时属性并使用了一个Bean代替字符串,问题得到解决。 - Virginie
顺便提一下,你的链接有问题,正确的在这里 - Virginie

0

如果我理解正确,在表单中还有一些其他验证失败。当提交的任何表单值未通过验证时,除非使用immediate,否则不会将任何提交的值应用于托管Bean。这就是为什么似乎你能够添加一个新行,但不能使用doStuff方法。你没有在doStuff中添加immediate

但是,有几件事情可以更加清洁和高效。

首先,action属性应该真正用于导航操作。JSF期望与action绑定的方法具有表示导航结果的返回值。void方法最好使用actionListener。有关actionactionListener之间差异的更多信息,请阅读此处:action和actionListener之间的区别

其次,为什么不将processupdate仅设置为数据表组件,这样您就不必担心其他表单验证了呢?以下是一个示例:
<h:form id="my-form">
    <p:dataTable value="#{testBean.list}" var="s" id="datatable">
        <p:column>
            <h:inputText value="#{s}"/>
        </p:column>
        <f:facet name="footer">
            <p:commandButton value="Add row" actionListener="#{testBean.addRow}"
               process=":my-form:datatable" update=":my-form:datatable" />
            <p:commandButton value="Do stuff" actionListener="#{testBean.doSomeLogic}"
               process=":my-form:datatable" update=":my-form:datatable" />
        </f:facet>
    </p:dataTable>
</h:form>

我的真实代码中有验证,但是在我用来尝试解决这个问题的示例中没有。因此,在这个示例中,process="@form"等同于process=":my-form"。基本上,你的代码和我的一模一样(我测试了,出现了同样的问题;单击“do stuff”,没有提交新数据)。不管怎样,感谢你关于actionListener和action的建议 :) - Virginie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接