PrimeFaces DataTable - 提交表单时视图中的选择设置为 null 并且表本身不在表单中

发布于 2025-01-15 06:27:32 字数 3676 浏览 0 评论 0原文

编辑:根据 Jasper 的评论,选择功能要求 p:dataTable 处于表单中,所以我的问题没有实际意义。

我在表单之外有一个数据表。当我提交表单(非 ajax)时,选择属性引用的字段在我的视图中设置为 null。 PrimeFaces 10.0.1 及更高版本会发生这种情况。在 10.0.0 和 8.x 中,该字段未被触及。

示例中的字段是DtView.selectedEntry

xhtml:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

<h:head>
   <title>PrimeFaces Test</title>
</h:head>
<h:body>

   <p:dataTable id="data-table" var="entry"
                value="#{dtView.entries}"
                rowKey="#{entry.id}"
                selection="#{dtView.selectedEntry}"
                selectionMode="single">
      <p:column headerText="Entry">
         <h:outputText value="#{entry}" />
      </p:column>
   </p:dataTable>

   <h:form id="frmTest">
      <div>
         <p:outputLabel for="@next" value="Selected: "/>
         <h:outputText id="selected-entry" value="#{dtView.selectedEntry}" />
      </div>
      <div>
         <p:commandButton value="save input"
                          ajax="false"
                          imediate="true"
                          update="@form :data-table"
                          action="#{dtView.submit()}" />
      </div>
   </h:form>

</h:body>
</html>

视图:

@Data
@Named
@ViewScoped
public class DtView implements Serializable {

    private List<Product> entries;
    private Product selectedEntry;

    @PostConstruct
    void setup() {
        entries = List.of(
                new Product(1, "entry 1"),
                new Product(2, "entry 2"),
                new Product(3, "entry 3")
        );
        selectedEntry = entries.get(0);
    }

    public String submit() {
        System.out.println("Selected entry: " + selectedEntry);
        return null;
    }
}

控制台(PrimeFaces 11.0.0 和 10.0.0):

Selected entry: null
Selected entry: Product(id=1, name=entry 1)

为了避免“null”,我可以将 p:dataTable 放入表单中,这样它就不会在应用请求值阶段或使用 ajax 进行处理命令按钮。我不确定为什么数据表在我的实际应用程序中的表单之外。

我期望不在视图中设置表单之外的值,但 dataTable 似乎不遵循这一点。新的PF行为是否更符合逻辑,而我的理解是错误的?


这一变化的原因似乎位于 SelectionFeature 中。

PF 8:只需调用 table.setSelection(null);https://github.com/primefaces/primefaces/blob/cd4fbdf1d9d4ae054da19b9a84001d0c34d142eb/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L78

PF 10.0.0: decodeSingleSelection() 不会调用 setSelection(),因为 !rowKeys.isEmpty() 计算结果为 false(空检查在 10.0.1 中消失): https://github.com/primefaces/primefaces/blob/10.0.0/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L84

11.0.0: decodeSingleSelection() 最终调用 setSelection() 将视图中的值设置为 null: https://github.com/primefaces/primefaces/blob/11.0.0/primefaces/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L87

edit: Based on Jasper's comment, the selection feature requires p:dataTable to be in a form, so my question is moot.

I have a DataTable outside of a form. When I submit the form (non-ajax), the field referenced by the selection attribute is set to null in my view. This happens for PrimeFaces 10.0.1 and higher. In 10.0.0 and 8.x, the field is not touched.

The field in the example is DtView.selectedEntry.

xhtml:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

<h:head>
   <title>PrimeFaces Test</title>
</h:head>
<h:body>

   <p:dataTable id="data-table" var="entry"
                value="#{dtView.entries}"
                rowKey="#{entry.id}"
                selection="#{dtView.selectedEntry}"
                selectionMode="single">
      <p:column headerText="Entry">
         <h:outputText value="#{entry}" />
      </p:column>
   </p:dataTable>

   <h:form id="frmTest">
      <div>
         <p:outputLabel for="@next" value="Selected: "/>
         <h:outputText id="selected-entry" value="#{dtView.selectedEntry}" />
      </div>
      <div>
         <p:commandButton value="save input"
                          ajax="false"
                          imediate="true"
                          update="@form :data-table"
                          action="#{dtView.submit()}" />
      </div>
   </h:form>

</h:body>
</html>

View:

@Data
@Named
@ViewScoped
public class DtView implements Serializable {

    private List<Product> entries;
    private Product selectedEntry;

    @PostConstruct
    void setup() {
        entries = List.of(
                new Product(1, "entry 1"),
                new Product(2, "entry 2"),
                new Product(3, "entry 3")
        );
        selectedEntry = entries.get(0);
    }

    public String submit() {
        System.out.println("Selected entry: " + selectedEntry);
        return null;
    }
}

Console (PrimeFaces 11.0.0 and then 10.0.0):

Selected entry: null
Selected entry: Product(id=1, name=entry 1)

To avoid the 'null' I can put p:dataTable inside a form, so it won't get processed during the apply request value phase or use ajax on the command button. I am not sure why the dataTable is outside a form in my real application to begin with.

I expected a value outside of a form not to be set in the view, but dataTable does not seem to follow this. Is the new PF behaviour more logical and my understanding is wrong?


The reason for this change seems to be located in SelectionFeature.

PF 8: just calls table.setSelection(null);:
https://github.com/primefaces/primefaces/blob/cd4fbdf1d9d4ae054da19b9a84001d0c34d142eb/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L78

PF 10.0.0: decodeSingleSelection() does not call setSelection() because !rowKeys.isEmpty() evaluates to false (empty check disappears in 10.0.1):
https://github.com/primefaces/primefaces/blob/10.0.0/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L84

11.0.0: decodeSingleSelection() eventually calls setSelection() to set the value in the view to null:
https://github.com/primefaces/primefaces/blob/11.0.0/primefaces/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L87

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文