p:datatable selectAllRows api 调用不触发 rowSelect 事件

p:datatable selectAllRows api calls don't trigger rowSelect Event

我有一个 p:dataTableselectionMode=multiple,它绑定了 rowSelectrowUnselect 事件:

<p:dataTable 
    widgetVar="myDatatable" 
    selectionMode="multiple" 
    selection="#{myBean.selection}">
    <p:ajax event="rowSelect" listener="#{myBean.onSelect}" />
    <p:ajax event="rowUnselect" listener="#{myBean.onUnselect}" />
... (columns)
</p:dataTable>

选择行工作正常,myBean.selection 已更新并调用 myBean.onSelect()

现在我想向 (un)select 所有项目添加按钮到我的工具栏。我创建了两个 <p:commandLink>s:

<p:commandLink onclick="PF('myDatatable').selectAllRows();" 
            update="actionbarForm">select all</p:commandLink>
<p:commandLink onclick="PF('myDatatable').unselectAllRows();" 
            update="actionbarForm">unselect all</p:commandLink>

selection 似乎有效,我可以看到所有项目都是 (un)selected。但是,myBean.selectionmyBean.onSelect() 都不是 updated/invoked。我必须做什么才能启用此功能?

这两个 PrimeFaces javascript api 调用绝不会与任何 ajax 事件交互。这可以在 selectAllRows() and unselectAllRows() 中的 datatable.js 中看到 如果您不使用 ajax 而是通过按钮使用普通的 'submit',您会看到 PrimeFaces 扩展了 selection 到服务器端的 'all'。为此,它将 selection 的 @all 值传递给服务器。

您还会在源代码中看到已经有一些代码可以发送 'toggleSelect` ajax 事件,所以我将它放在一个扩展 PrimeFaces 数据表的函数中:

PrimeFaces.widget.DataTable.prototype.fireToggleSelectEvent = function(checked) {
    //fire toggleSelect event
    if(this.cfg.behaviors) {
        var toggleSelectBehavior = this.cfg.behaviors['toggleSelect'];

        if(toggleSelectBehavior) {
            var ext = {
                    params: [{name: this.id + '_checked', value: checked}
                ]
            };

            toggleSelectBehavior.call(this, ext);
        }
    }
}

通过小部件调用 (un)selectAllRows() 后,您也可以调用此函数,使用 true (select) 或 false (unselect ) 值作为参数。

如果您随后将 toggleSelect ajax 添加到您的数据表

<p:ajax event="toggleSelect" listener="#{dtSelectionView.onToggleSelect}" update=":form:msgs" />

并在您的 bean 中添加一个处理程序:

public void onToggleSelect(ToggleSelectEvent event) {
    FacesMessage msg = new FacesMessage(event.isSelected() ? "All Selected" : "All Unselected");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

一切正常。 (PrimeFaces 6.0,针对展示柜测试的代码)

您还可以覆盖 PrimeFaces 中的 (un)selectAllRows datatable.js 并在最后调用 fireToggleSelectEvent,因此所有功能都在一个函数调用中(或将两个单独的调用合并为一个自定义函数)。