java - 在 JSF/RichFaces `dataTable` 中拥有 boolean 复选框的正确方法是什么?

标签 java jsf jakarta-ee

在 JSF/RichFaces 的每一行中添加 boolean 复选框的正确方法是什么 dataTable ?我尝试了以下代码片段:

<rich:dataTable id="customerList"
               var="_customer"
             value="#{customerList.resultList}"
          rendered="#{not empty customerList.resultList}" >
    <h:column>
        <h:selectBooleanCheckbox
            value="#{customerList.selectedCustomers[_customer.id]}" />
    </h:column>
...
</rich:dataTable>

我设置了我的customerList有一个Map<Integer, Boolean> selectedCustomers 。事情似乎工作得很好,除了显然复选框是由排序索引映射的,而不是实际上由 ID 映射的,这给我带来了问题。

例如,当我打开上面的页面并选中第一行中的复选框并按“删除”按钮时,一切正常,并且页面会在没有选定客户的情况下重新加载。但是,如果我按“刷新”或“重新加载”(并接受浏览器重新发送数据的警告),则第一行中的客户将被删除!

我应该怎样做才能使复选框仅与所选 ID 绑定(bind)?

最佳答案

如果您只想处理刷新,请查看导航规则中的redirect 选项。

  <navigation-rule>
    <display-name>navBack</display-name>
    <from-view-id>/navBack.jsp</from-view-id>
    <navigation-case>
      <from-outcome>navTo</from-outcome>
      <to-view-id>/navTo.jsp</to-view-id>
      <redirect />
    </navigation-case>
  </navigation-rule>

如果您也想处理后退按钮和多个窗口情况,请继续阅读。

您可以使用隐藏字段和行级工件来检测这一点。基本上,您可以根据提交表单时收到的 ID 来检查发送给客户端的 ID。

public class SafeRow {
  private final String rowId;
  private String rowIdClient;
  private String name;
  private boolean delete;

  public SafeRow(String name) {
    this();
    this.name = name;
  }

  public SafeRow() {
    rowId = UUID.randomUUID().toString();
  }

  public String getRowId() { return rowId; }    
  public void setRowId(String rowIdClient) { this.rowIdClient = rowIdClient; }

  public boolean isStateConsistent() {
    return rowId.equals(rowIdClient);
  }

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }

  public boolean isDelete() { return delete; }
  public void setDelete(boolean delete) { this.delete = delete; }
}

表格数据:

public class SafeUpdateBean {
  private final List<SafeRow> data = new ArrayList<SafeRow>();

  public SafeUpdateBean() {
    data.add(new SafeRow("Bill"));
    data.add(new SafeRow("Ben"));
    data.add(new SafeRow("Sue"));
  }

  public List<SafeRow> getData() { return data; }

  public String deleteSelected() {
    Iterator<SafeRow> all = data.iterator();
    while (all.hasNext()) {
      SafeRow row = all.next();
      if (!row.isStateConsistent()) {
        System.err.println("Caught inconsistency on " + row.getRowId());
      } else if (row.isDelete()) {
        all.remove();
      }
    }
    return null;
  }
}

View :

<h:form>
  <h:dataTable value="#{safeUpdateBean.data}" var="row">
    <h:column>
      <h:inputHidden value="#{row.rowId}" />
      <h:selectBooleanCheckbox value="#{row.delete}" />
      <h:outputText value="#{row.name}" />
    </h:column>
  </h:dataTable>
  <h:commandButton value="delete selected"
    action="#{safeUpdateBean.deleteSelected}" />
</h:form>

此演示代码使用一个简单的 session bean,但希望您清楚如何将其调整为更合理的内容。这不是您可以做的唯一事情 - 例如,您可以执行更一般的重复表单提交。像 Seam 这样的第 3 方框架也添加了对此类事情的处理。

关于java - 在 JSF/RichFaces `dataTable` 中拥有 boolean 复选框的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1486236/

相关文章:

java - 如何在房间数据库查询中使用预定义的字符串?

java - a4j :commandLink executes action after double clicking

jquery - Primefaces 文件上传,将文件拖放到 p :fileUpload anywhere in the page 之外

java - 使用 Spring 3 的动态作业调度

java - UTC Unix 时间戳存储在错误时区的 Java 程序中的 HSQLDB 中

java - 菜单图标不会出现

Java 嵌套 while 循环未按预期运行

java - 有人可以确认一下 : BigDecimal not rendered with pattern

java - 如何在j2EE应用程序中通过JMS和Websphere MQ发送和接收xml文件

mysql - 使用 Hibernate 查找短语与数据库条目的部分匹配