【问题标题】:Primefaces Datatable doesnt update selected rowsPrimefaces Datatable 不更新选定的行
【发布时间】:2012-11-07 13:21:21
【问题描述】:

我有一个简单的问题。我有一个 Primefaces 数据表。当用户单击一行时,我希望更新支持 bean 中的 selected rows 属性。如果提交 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;
    }
}

根据回复,我已经像这样更新了数据表:

    <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。有什么想法吗?

【问题讨论】:

  • 您的意思是,您想在用户点击该行后立即设置所选行?为什么不只是稍后在这些行上执行所需的操作? (默认情况下会发生)
  • 是的,没错。我采用这种方法的原因是我有一个 PrimeFaces Stack 菜单。当用户单击其中一个 MenuItem 时,会触发 ActionListener。当我尝试从 ActionListener 访问选定的行时,它们尚未设置。现在我想如果可以从 MenuItem 提交表单,您的目的是可能的。
  • 嗯……我还是会发布答案。

标签: jsf primefaces


【解决方案1】:

我相信您的声明“提交表单时有效”是解决方案。

我有一个类似的问题,我的页面有多个面板,第一个面板是人员列表,一旦选择某人,详细信息就会加载到以下面板中。

所以我的 rowSelect 监听器正在触发,但我的 bean 总是有 null 供我选择。仅供参考,我的 rowSelect 侦听器更新了一个 p:outputPanel,它包装了我的详细信息面板。 My detail panels are only rendered when the selection is not null.

我刚刚用 h:form 包装了数据表,一切都开始工作了,只需选择一行。

现在我为我的 bean 使用 Spring Session Scoped Component 来容纳数据列表和选择,并为我的控制器使用 Spring 单例组件来进行 rowSelect 操作。但它仍然适用于您的示例。

【讨论】:

    【解决方案2】:
    <p:column headerText="Test">
        <h:outputText value="#{v.value}" />
    </p:column>
    

    去掉h:outputText标签,如下使用

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

    【讨论】:

      【解决方案3】:

      您可以在&lt;p:ajax&gt; 中使用rowSelect 事件。

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

      然而,在这种情况下,这几乎没有意义。如果您还想在其上附加 listenerupdate 属性,那会更有意义。例如

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

      如果您也想取消选择行,请添加另一个挂钩rowUnselect

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

      另见:

      【讨论】:

      • 感谢您的回复。我试过你的建议。仍然没有运气。我已经更新了我的问题以反映它。
      • 呃,“而且这只在点击一行时才调用setter”这正是他们应该做的。一旦它们被(取消)选择更新模型值。这不是你最终想要的吗? “当用户点击一行时,我希望更新支持 bean 中的 selected rows 属性” 那么你在这里具体问什么?
      • 是的,这是一个错字,很抱歉,我把它改成了 getter。
      • 这里显然不会调用getter。只有当视图真正需要它时才会调用它。为什么要调用特定的吸气剂?这应该是您在 JSF 应用程序中最不关心的问题,因为 getter(和 setter)不应该执行业务逻辑。具体的功能需求是什么?您是否在 getter 中放置了一些业务逻辑?那它应该怎么做呢?
      • 我不想,我希望调用 setter,而不是 getter。但是当我尝试使用 ajax 标签的解决方案并单击一行时,调用的是 getter,而不是 setter。
      【解决方案4】:

      只需在数据表中添加&lt;p:ajax event="rowSelect" /&gt;

      <p:dataTable selection="#{customerView.selectedEntity}" selectionMode="single">
          <p:ajax event="rowSelect" />
      <!--more code-->
      </p:dataTable>
      

      这将在您的支持 bean 中调用 setSelectedEntity(),因此您可以在 actionListener 触发时设置它

      如果您想从数据表表单(不会提交值)外部调用 actionListener,这很有用

      【讨论】:

      • 我在上面的例子中试过这个,但它似乎仍然不起作用。我将尝试使用单个项目而不是选定行的数组。
      猜你喜欢
      • 2018-03-24
      • 2014-09-02
      • 2018-07-15
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 2012-01-25
      相关资源
      最近更新 更多