2013-03-06 3 views
7

Основные шрифты 3.5, Mojarra 2.1.14. Это мой PF DataTable, он содержит один нередактируемый столбец булева под названием «автоматическая» и редактируемый «метка» колонок:Как обновить определенную строку в файле «Первичные»

<p:dataTable value="#{bean.contents}" paginator="true" var="row" 
    editable="true" editMode="cell" rows="25" rowsPerPageTemplate="10,25,50" id="list"> 
    <p:column> 
     <f:facet name="header"><h:outputText value="header1" /></f:facet> 
     <p:selectBooleanCheckbox value="#{row.automatic}" disabled="true" id="isAutomatic"></p:selectBooleanCheckbox> 
    </p:column> 
    <p:column> 
     <f:facet name="header"><h:outputText value="header2" /></f:facet> 
     <p:cellEditor> 
      <f:facet name="output"> 
       <h:outputText value="#{row.label}"></h:outputText> 
      </f:facet> 
      <f:facet name="input"> 
       <p:inputText value="#{row.label}"></p:inputText> 
      </f:facet> 
     </p:cellEditor> 
    </p:column> 
    <p:ajax event="cellEdit" process="@this" listener="#{myBean.onEditLabel}" update="isAutomatic"/> 
</p:dataTable> 

Cell слушатель редактировать событие:

public void onEditLabel(CellEditEvent event) { 
    Object oldValue = event.getOldValue(); 
    Object newValue = event.getNewValue(); 

    if(newValue != null && !newValue.equals(oldValue)) { 
     DataTable s = (DataTable) event.getSource(); 
     MyEntity d = (MyEntity) s.getRowData(); 
     try { 
      d.setAutomatic(false); 
      myDAO.save(d); 
      addMessage("Change saved!"); 
     } catch (Exception ex) { 
      addErrorMessage("Label could not be saved!"); 
      getFacesContext().validationFailed(); 
     } 
    } 
} 

Клетка редактор работает, отправляет данные слушателю, и он сохраняется в базе данных. Флаг «автоматический» также очищается при прослушивании событий редактирования ячейки и корректно сохраняется в базе данных. Проблема в том, что флажок «автоматический» не обновляется на клиенте.

Я также попытался

<p:ajax event="cellEdit" process="@this" listener="#{myBean.onEditLabel}" update="list"/> 

который правильно обновил флажок, но и вызывает внимание к потере, а пропускная способность отходов.

Как я могу обновить только определенную ячейку после того, как событие cellEdit запущено?

ответ

5

Тег p:ajax находится внутри p:dataTable Нет в определенной строке или столбце, поэтому вы так легко обновляете некоторый относительный идентификатор компонента. Вы можете с помощью RequestContext уточнить определенный компонент в ячейке. Таким образом, удалить update из p:ajax и добавить в ваш метод onEditLabel:

RequestContext.getCurrentInstance().update(
    s.getClientId(FacesContext.getCurrentInstance()) + 
    ":" + event.getRowIndex() + 
    ":isAutomatic" 
); 

Как вы можете видеть, идентификатор компонента внутри ячейки имеет номер строки, прежде чем идентификатор вы назначили.

+0

Спасибо! Это работает, но определенно это не лучшая практика. Во-первых, я полагаюсь на конкретное соглашение об именах компонентов. Во-вторых, мой контроллер теперь содержит логику интерфейса (ID просмотра). Лучшим решением было бы добавить такую ​​возможность в PF DataTable. Вздох. :) – rootkit

+1

Я не совсем согласен с тобой. Базирующийся компонент тесно связан с уровнем представления (например, с помощью метода bean bean-метода прослушивания AJAX-прослушивателя). Было бы плохо, если бы вы поместили бизнес-логику в бэк-файл. Я согласен с тем, что добавление id в бэк-файл не очень приятный, но в этот момент я не вижу никакого простого решения. – partlov

+0

Я согласен, что нет простого решения, это нужно будет сделать. Еще раз спасибо! – rootkit

2

Я считаю, что вы можете решить эту проблему, не зная подробностей идентификатора компонента, который хотите обновить. Вы можете передать его в качестве параметра для bean-компонента.

Сначала привяжите компонент, который вы хотите обновить. Вам действительно не нужен компонент, к которому привязан этот компонент. Вам просто нужно определить некоторое значение, которое вы можете использовать для идентификации этого компонента позже в своем JSF. Таким образом, в вашем случае вы бы сделали что-то вроде:

<p:selectBooleanCheckbox binding="#{isAutomaticComponent}" value="#{row.automatic}" disabled="true" id="isAutomatic"></p:selectBooleanCheckbox> 

Теперь обращайтесь к компоненту при обновлении. то есть:

<p:ajax event="cellEdit" process="@this" listener="#{myBean.onEditLabel(isAutomaticComponent.clientId)}" /> 

Теперь вы можете обновить компонент из метода событий cellEdit, не зная содержимого идентификатора. т.е.:

public void onEditLabel(CellEditEvent event, String idOfComponentToUpdate) { 
... 
RequestContext.getCurrentInstance().update(idOfComponentToUpdate); 
... 
+0

Вы на самом деле пробовали это? Интересно, корректно ли будет работать привязка компонента внутри datatable. Также я считаю, что вы можете использовать что-то вроде # {component.clientId}, см. Http: // stackoverflow.com/questions/4469992/how-to-get-id-of-call-component-in-get-method – rootkit

+0

Моя ситуация немного отличается, поэтому я не пробовал именно этот сценарий, но я что-то сделал очень похожий. Я считаю, что это сработает для сценария, опубликованного здесь. И да. Связывание компонентов работает внутри данных. Это ближе к моему сценарию на самом деле, так как я хотел обновить идентификатор кнопки в строке таблицы, но это было неприятно, так как строки в таблице были динамическими, и таким образом был идентификатор кнопки. Прохождение идентификатора компонента таким способом было лучшим решением, которое я смог найти. –

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