【问题标题】:Can't get selected row of p:dataTable when used inside cc:implementation在 cc:implementation 中使用时无法获取 p:dataTable 的选定行
【发布时间】:2014-11-08 23:16:36
【问题描述】:

我试图在 PrimeFaces DataTable 中获取选定的行,但是当在我的 bean 上调用事件时,对象的值为 null。我已经阅读了一些关于此的文章。这似乎是与rowKey参数有关的问题。当我使用DataTable组件而不使用复合时,我可以正常获取对象值。据我了解,当我使用复合时,默认情况下视图是 Object 类型的。这意味着不能将 rowKey 参数分配给“#{item.id}”,因为 Object 类型没有名为 id 的属性。经过深入调查,我发现问题出在 DataTable 类的 queueEvent 方法上。

@Override
public void queueEvent(FacesEvent event) {
    FacesContext context = getFacesContext();

    if(isRequestSource(context) && event instanceof AjaxBehaviorEvent) {
        setRowIndex(-1);
        Map<String,String> params = context.getExternalContext().getRequestParameterMap();
        String eventName = params.get(Constants.RequestParams.PARTIAL_BEHAVIOR_EVENT_PARAM);
        String clientId = this.getClientId(context);
        FacesEvent wrapperEvent = null;

        AjaxBehaviorEvent behaviorEvent = (AjaxBehaviorEvent) event;

        if(eventName.equals("rowSelect")||eventName.equals("rowSelectRadio")||eventName.equals("contextMenu")
                ||eventName.equals("rowSelectCheckbox")||eventName.equals("rowDblselect")) {
            String rowKey = params.get(clientId + "_instantSelectedRowKey");
            wrapperEvent = new SelectEvent(this, behaviorEvent.getBehavior(), this.getRowData(rowKey)); 
        }
        else if(eventName.equals("rowUnselect")||eventName.equals("rowUnselectCheckbox")) {
            String rowKey = params.get(clientId + "_instantUnselectedRowKey");
            wrapperEvent = new UnselectEvent(this, behaviorEvent.getBehavior(), this.getRowData(rowKey));
        }
        else if(eventName.equals("page")) {
            int rows = this.getRowsToRender();
            int first = Integer.parseInt(params.get(clientId + "_first"));
            int page = rows > 0 ? (int) (first / rows) : 0;

            wrapperEvent = new PageEvent(this, behaviorEvent.getBehavior(), page);
        }
        else if(eventName.equals("sort")) {
            SortOrder order;
            UIColumn sortColumn;

            if(isMultiSort()) {
                String[] sortDirs = params.get(clientId + "_sortDir").split(",");
                String[] sortKeys = params.get(clientId + "_sortKey").split(",");

                order = SortOrder.valueOf(sortDirs[sortDirs.length - 1]);
                sortColumn = findColumn(sortKeys[sortKeys.length - 1]);
            } 
            else {
                order = SortOrder.valueOf(params.get(clientId + "_sortDir"));
                sortColumn = findColumn(params.get(clientId + "_sortKey"));
            }

            wrapperEvent = new SortEvent(this, behaviorEvent.getBehavior(), sortColumn, order);
        }
        else if(eventName.equals("filter")) {
            wrapperEvent = new FilterEvent(this, behaviorEvent.getBehavior(), getFilteredValue(), getFilters());
        }
        else if(eventName.equals("rowEdit")||eventName.equals("rowEditCancel")||eventName.equals("rowEditInit")) {
            int rowIndex = Integer.parseInt(params.get(clientId + "_rowEditIndex"));
            setRowIndex(rowIndex);
            wrapperEvent = new RowEditEvent(this, behaviorEvent.getBehavior(), this.getRowData());
        }
        else if(eventName.equals("colResize")) {
            String columnId = params.get(clientId + "_columnId");
            int width = Integer.parseInt(params.get(clientId + "_width"));
            int height = Integer.parseInt(params.get(clientId + "_height"));

            wrapperEvent = new ColumnResizeEvent(this, behaviorEvent.getBehavior(), width, height, findColumn(columnId));
        }
        else if(eventName.equals("toggleSelect")) {
            boolean checked = Boolean.valueOf(params.get(clientId + "_checked"));

            wrapperEvent = new ToggleSelectEvent(this, behaviorEvent.getBehavior(), checked);
        }
        else if(eventName.equals("colReorder")) {
            wrapperEvent = behaviorEvent;
        }
        else if(eventName.equals("rowToggle")) {
            boolean expansion = params.containsKey(clientId + "_rowExpansion");
            Visibility visibility = expansion ? Visibility.VISIBLE : Visibility.HIDDEN;
            String rowIndex = expansion ? params.get(clientId + "_expandedRowIndex") : params.get(clientId + "_collapsedRowIndex");
            setRowIndex(Integer.parseInt(rowIndex));

            wrapperEvent = new ToggleEvent(this, behaviorEvent.getBehavior(), visibility, getRowData());
        }
        else if(eventName.equals("cellEdit")) {
            String[] cellInfo = params.get(clientId + "_cellInfo").split(",");
            int rowIndex = Integer.parseInt(cellInfo[0]);
            int cellIndex = Integer.parseInt(cellInfo[1]);
            int i = -1;
            UIColumn column = null;

            for(UIColumn col : this.getColumns()) {
                if(col.isRendered()) {
                    i++;

                    if(i == cellIndex) {
                        column = col;
                        break;
                    }
                }
            }

            wrapperEvent = new CellEditEvent(this, behaviorEvent.getBehavior(), rowIndex, column);
        }

        wrapperEvent.setPhaseId(event.getPhaseId());

        super.queueEvent(wrapperEvent);
    }
    else {
        super.queueEvent(event);
    }
}

在以下行中找不到 rowKey 值:

String rowKey = params.get(clientId + "_instantSelectedRowKey");

取而代之的是,我在一个名为 selection (clientId + "_selection") 的键中拥有所选行的 ID。当我直接使用 DataTable 而不使用 cc:implementation 时,上面的行有效。

当我必须在复合中使用 DataTable 时,是否有人可以替代获取所选行?

这是我用来显示数据的组合的一部分。

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

<cc:attribute name="mBeanOnRowSelect" required="true"
        method-signature="void action(javax.faces.event.AjaxBehaviorEvent)" />

<cc:attribute name="mBeanOnRowUnselect" required="true"
        method-signature="void action(javax.faces.event.AjaxBehaviorEvent)" />

<cc:implementation>
    <p:dataTable id="grid" var="item" value="#{cc.attrs.mBeanDataLazy}"
        paginator="true" rows="#{cc.attrs.rows}" paginatorPosition="bottom"
        currentPageReportTemplate="({currentPage} #{msgs.label_of} {totalPages})"
        paginatorTemplate="{CurrentPageReport} {FirstPageLink}
                                {PreviousPageLink} {PageLinks} {NextPageLink} 
                                {LastPageLink} {RowsPerPageDropdown}"
        rowsPerPageTemplate="#{cc.attrs.rowsPerPage}" lazy="true"
        rowKey="#{item.id}"
        selection="#{cc.attrs.selectionBean[cc.attrs.selectionProperty]}"
        emptyMessage="#{msgs['label_grid_emptyMessage']}"
        filteredValue="#{cc.attrs.mBeanFilteredItems}"
        widgetVar="#{cc.attrs.itemsGrid}" resizableColumns="true"
        filterEvent="enter" rendered="#{cc.attrs.renderGrid}"
        scrollable="#{cc.attrs.gridScrollable}" scrollWidth="1200">

        <!-- Header -->
        <cc:insertFacet name="header" />

        <!-- Colunas do grid -->
        <p:column selectionMode="#{cc.attrs.gridSelection}" width="20"
            resizable="false" />

        <!-- Marca a linha do grid -->
        <f:ajax event="rowSelect" listener="#{cc.attrs.mBeanOnRowSelect}"
            render="gridButtons grid" />

        <!-- Desmarca a linha do grid -->
        <f:ajax event="rowUnselect" listener="#{cc.attrs.mBeanOnRowUnselect}"
            render="gridButtons grid" />

        <!-- Colunas do grid -->
        <cc:insertChildren />
    </p:dataTable>
</cc:implementation>
</html>

这是选择行时调用的 bean 方法。

public void onRowSelect(AjaxBehaviorEvent event)
            throws AbortProcessingException {
    super.onRowSelect(event);
}

【问题讨论】:

  • 我没有看到为您的数据表指定 selectionMode。你试过添加一个吗?
  • 我在第一列中使用了 selectionMode。
  • 我也试过参数rowSelectMode,但没有成功。
  • 能把你用的mBeanDataLazy型号的代码加进去吗?

标签: jsf jsf-2 primefaces datatable composite-component


【解决方案1】:

我找到了问题。

<!-- Marca a linha do grid -->
<f:ajax event="rowSelect" listener="#{cc.attrs.mBeanOnRowSelect}"
    render="gridButtons grid" />

<!-- Desmarca a linha do grid -->
<f:ajax event="rowUnselect" listener="#{cc.attrs.mBeanOnRowUnselect}"
    render="gridButtons grid" />

Ajax 事件应该属于 PrimeFaces 库。

当我在两个事件中将 f: 替换为 p: 时,我会在 DataTable 类中获得 rowKey,从而获得选定的行。

【讨论】:

    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 2022-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多