Primefaces数据表格不会更新所选行

3
我有一个简单的问题。我有一个Primefaces数据表。当用户点击一行时,我希望在后端bean中更新所选行的属性。如果提交包含Datatable的表单,可以实现此目的,但我希望异步完成。我已经阅读了这个问题的各种问题,但仍然无法找到解决方案。
这里是一个小例子来演示这个问题:
测试JSF页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Facelet Title</title>
</h:head>
<h:body>
    <p:dataTable var="v" value="#{test.values}" selectionMode="multiple"
                 selection="#{test.selectedValue}" rowKey="#{v.value}" >
        <p:column headerText="Test">
            <h:outputText value="#{v.value}" />
        </p:column>
    </p:dataTable>
</h:body>

后备Bean:

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.stack.Stack;

@ManagedBean
@ViewScoped
public class Test 
{

    private Value[] selectedValues;

    public List<Value> getValues()
    {
        List<Value> retVal = new ArrayList<Value>();
        retVal.add(new Value("a"));
        retVal.add(new Value("b"));
        return retVal;
    }

    public Value[] getSelectedValues() {
        return selectedValues;
    }

    public void setSelectedValues(Value[] selectedValues) {
        this.selectedValues = selectedValues;
    }
}

以下是一个简单的POJO:

public class Value {

    private String value;
    public Value(String value)
    {
        this.value = value;
    }

    public String getValue()
    {
        return value;
    }

    public void setValue(String value)
    {
        this.value = value;
    }
}

根据反馈,我已经更新了Datatable,如下所示:
    <p:dataTable id="dt" var="v" value="#{test.values}" selectionMode="multiple"
                 selection="#{test.selectedValues}" rowKey="#{v.value}" >
        <p:column headerText="Test">
            <h:outputText value="#{v.value}" />
        </p:column>
        <p:ajax event="rowSelect"/>
        <p:ajax event="rowUnselect" />
    </p:dataTable>

然而,这仍然未调用setter setSelectedValues();我让它们也说:
    <p:ajax event="rowSelect" update="@this" />
    <p:ajax event="rowUnselect" update="@this" />

只有在点击行时才会调用getter方法。有任何想法吗?

你的意思是,当用户点击行时,你想立即设置所选行吗?为什么不在执行所需操作时稍后再设置它们呢?(这是默认情况下会发生的) - BalusC
是的,这是正确的。我采取这种方法的原因是我有一个PrimeFaces堆栈菜单。当用户单击其中一个菜单项时,会触发ActionListener。当我尝试从ActionListener访问所选行时,它们还没有被设置。现在,如果可以从MenuItem提交表单,那么我想你提出的解决方案是可能可行的。 - user489041
好吧...我还是会发布一个答案。 - BalusC
4个回答

4
您可以在<p:ajax>中使用rowSelect事件。
<p:dataTable ...>
    ...
    <p:ajax event="rowSelect" />
</p:dataTable>

但是在这种情况下,这样做意义不大。如果你想要在那个位置连接一个listener或者一个update属性,那么这样做会更有意义。例如:

<p:dataTable ...>
    ...
    <p:ajax event="rowSelect" update="menu" />
</p:dataTable>

如果您想要钩住行的取消选择,可以再添加一个钩子来钩住 rowUnselect

<p:dataTable ...>
    ...
    <p:ajax event="rowSelect" />
    <p:ajax event="rowUnselect" />
</p:dataTable>

另请参阅:


谢谢您的回复。我已经尝试了您的建议,但仍然没有成功。我已经更新了我的问题以反映这一点。 - user489041
这里显然不会调用getter。只有当视图真正需要它时才会调用。你为什么想要调用特定的getter?在JSF应用程序中,这应该是你最不用担心的,因为getter(和setter)不应该执行业务逻辑。具体的功能需求是什么?你是否在getter中放置了一些业务逻辑?那么它应该做什么? - BalusC
我不希望调用getter,而是希望调用setter。但是当我尝试使用ajax标签的解决方案并单击一行时,仍然会调用getter而不是setter。 - user489041
抱歉,使用Mojarra 2.1.14和PrimeFaces 3.4.1对我来说运行良好。你的问题是由其他地方引起的,目前提供的代码或信息中没有显示出来。 - BalusC
有趣,谢谢你的帮助,我会试着调整它。我弄清楚后会更新的。 - user489041
显示剩余4条评论

3
只需在您的数据表内添加<p:ajax event="rowSelect" />即可。
<p:dataTable selection="#{customerView.selectedEntity}" selectionMode="single">
    <p:ajax event="rowSelect" />
<!--more code-->
</p:dataTable>

当actionListener触发时,这将在您的后备bean中调用setSelectedEntity()方法,因此您已经设置了它

如果您想从数据表格表单外部调用actionListener(不会提交该值),则此方法很有用


我已经在上面的示例中尝试过了,但似乎仍然不起作用。我将尝试使用单个项目而不是选定行的数组。 - user489041

2
我相信你的说法“在提交表单时工作”是解决方案。
我遇到了类似的问题,我的页面有多个面板,第一个面板是人员列表,一旦选择某个人,则会在以下面板中加载详细信息。
因此,我的rowSelect监听器正在触发,但是我的bean始终对我的选择为null。顺便说一下,我的rowSelect监听器更新了一个包装我的详细面板的p:outputPanel。只有在选择不为null时才呈现我的详细面板。
我只需用h:form包装数据表格,就可以通过选择一行使一切开始工作。
现在我使用了Spring,Session Scoped组件来存储数据列表和选择,以及Spring单例组件来控制rowSelect操作。但是它仍然适用于您的示例。

-2
<p:column headerText="Test">
    <h:outputText value="#{v.value}" />
</p:column>

移除 h:outputText 标签,使用如下

<p:column headerText="Test">
    #{v.value}
</p:column>

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