2014-09-15 1 views
0

Я пытаюсь получить выбранную строку в DataTable PrimeFaces, но когда событие вызывается в моем бине, значение объекта равно null. Я прочитал некоторые статьи об этом. Кажется, это проблема, связанная с параметром rowKey. Когда я использую компонент DataTable без использования составного элемента, я могу получить значение объекта в обычном режиме. Насколько я понимаю, когда я использую композит, по умолчанию представление имеет тип Object. Это означает, что параметр rowKey нельзя присвоить «# {item.id}», потому что тип Object не имеет атрибута с именем id. Проведя более глубокое исследование, я обнаружил, что проблема начинается с метода queueEvent в классе DataTable.Не удается получить выбранную строку p: dataTable при использовании внутри cc: реализация

@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"); 

Вместо этого, у меня есть идентификатор выбранных линий в качестве ключевого называется отбора (ClientID + «_selection»). Строка выше работает, когда я напрямую использую DataTable, не используя реализацию cc:.

Есть ли у кого-нибудь альтернатива получить выбранную строку, когда мне нужно использовать 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); 
} 
+0

Я не вижу, чтобы для вашего datatable задан параметр 'selectionMode'. Вы пытались добавить его? – RevanProdigalKnight

+0

Я использовал selectMode в первом столбце. –

+0

Я также пробовал параметр rowSelectMode, но я не получил успеха. –

ответ

0

Я нашел проблему.

<!-- 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: в обоих случаях я получаю rowKey в классе DataTable и, следовательно, в выбранной строке.

 Смежные вопросы

  • Нет связанных вопросов^_^