【发布时间】: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