【问题标题】:PrimeFaces DataTable CellEdit get entity/objectPrimeFaces DataTable CellEdit 获取实体/对象
【发布时间】:2013-09-07 19:42:31
【问题描述】:

我有一个基于 List 显示各种实体的数据表。当我选择一个单元格进行编辑时,我希望能够以某种方式获取实体以便更新它。 当然还有 event.getRowIndex,然后我可以将它与 List 一起使用,但这并不总是很方便。是否有其他方法可以从 CellEditEvent 获取实体?

【问题讨论】:

    标签: jsf primefaces facelets


    【解决方案1】:

    一种方法是以编程方式 EL 评估当前的<p:dataTable var>

    给定一个

    <p:dataTable value="#{bean.entities}" var="entity">
    

    你可以得到它如下

    public void onCellEdit(CellEditEvent event) {
        FacesContext context = FacesContext.getCurrentInstance();
        Entity entity = context.getApplication().evaluateExpressionGet(context, "#{entity}", Entity.class);
        // ...
    }
    

    如果您对 CellEditEvent 参数不感兴趣,另一种方法是通过将当前迭代的实体作为参数传递来完全覆盖 CellEditEvent 参数:

    <p:ajax event="cellEdit" listener="#{bean.onCellEdit(entity)}" />
    

    public void onCellEdit(Entity entity) {
        // ...
    }
    

    请注意,您不能保留 CellEditEvent 并传递其他参数。否则显然会给出这个答案。

    【讨论】:

    • 好吧,我需要 CellEditEvent,如果可能的话,最方便的方法是以某种方式将 CellEditEvent 作为参数与实体一起包含在内。产生一个方法:public void onCellEdit(CellEditEvent event, Entity entity)。否则我可能会选择第一种方式。
    • 你不能传递额外的参数。相关:stackoverflow.com/questions/3909267/… 所以是的,第一条路就是要走的路。如有必要,您可以将该样板代码隐藏到实用程序方法中。或者,如果你碰巧使用JSF utility library OmniFaces,就使用Entity entity = Faces.evaluateExpressionGet("#{entity}")
    【解决方案2】:

    我一直在努力解决这个问题二,我不喜欢依赖 var 名称,所以我找到了这个解决方案:

    public void onCellEdit(CellEditEvent event) {  
        Entity entity =(Entity)((DataTable)event.getComponent()).getRowData();
    }
    

    注意,实体更新后可以直接合并到数据库中,也可以获取旧值。 PS:感谢@BalusC 所做的一切:)

    【讨论】:

      【解决方案3】:

      我喜欢@user1928596 的回答,所以我对其进行了扩展,以获取单元格表示的确切数据点并仅更新它。这确实将数据表列标题文本与后端代码耦合,但我不知道有更好的方法来做到这一点。

      真正让我惊讶的是,当我编辑数据表中的数据时,支持 bean 中的数据也发生了变化。我不需要 cellEditEvent.getNewValue() 因为视图中的数据以某种方式绑定到支持 bean 中的数据。我以为它只是显示。 onCellEdit() 方法末尾的日志语句旨在显示 Event 对象的旧值和新值,但它只显示新值。

      这是单元格可编辑的数据表:

      这是显示代码:

          <p:dataTable id="facilitatorAdminEvents" var="event" value="#{testBean.facilitatorEvents}" editable="true" editMode="cell">
                <p:ajax event="cellEdit" listener="#{testBean.editEvent}" update="facilitatorAdminEvents" />
              <p:column headerText="Event Name"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.name}"></h:outputText></f:facet><f:facet name="input"><p:inputText value="#{event.name}"  style="width:100%" /></f:facet></p:cellEditor></p:column>
              <p:column headerText="Start Date"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.startdate}"><f:convertDateTime pattern="M/d/yyyy" /></h:outputText>
                  </f:facet><f:facet name="input"><p:calendar id="eventStartdate" value="#{event.startdate}" effect="fold" /></f:facet></p:cellEditor>
              </p:column>
              <p:column headerText="End Date"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.enddate}"><f:convertDateTime pattern="M/d/yyyy" /></h:outputText>
                  </f:facet><f:facet name="input"><p:calendar id="eventEnddate" value="#{event.enddate}" effect="fold" /></f:facet></p:cellEditor>
              </p:column>
              <p:column headerText="Status"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.status}" /></f:facet>
                  <f:facet name="input">
                          <p:selectOneMenu id="eventstatuses" value="#{event.status}" style="width: 100%; margin: auto; " scrollHeight="80" showHeader="false" label="Statuses">
                              <f:selectItems value="#{testBean.eventStatuses}" var="status" itemLabel="#{status}" />
                          </p:selectOneMenu>
                  </f:facet></p:cellEditor>
              </p:column>
              <p:column id="delete" style="text-align: center; vertical-align: middle; min-width: 54px; ">
                  <p:commandButton update="facilitatorAdminEvents" icon="ui-icon-close" actionListener="#{testBean.deleteEvent(event.id)}"></p:commandButton>
              </p:column>
          </p:dataTable>
      

      还有 onCellEdit 方法(我将其命名为 editEvent()):

      public void editEvent(CellEditEvent cellEditEvent) {
          Object newValue = cellEditEvent.getNewValue();
          String columnHeader = cellEditEvent.getColumn().getHeaderText();
          Event editedEvent = (Event) ((DataTable) cellEditEvent.getComponent()).getRowData();
          Event eventBeforeEdit = null;
          for (Event thisEvent : events) { // Find this event in the list of cached events.
              if (editedEvent.getId() == thisEvent.getId()) {
                  eventBeforeEdit = thisEvent;
              }
          }
          log.info("Updating event " + eventBeforeEdit + " to " + editedEvent);
          SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
          String update = null;
          if ("Event Name".equals(columnHeader)) {
              update = "update events set name = '" + newValue + "' where id = " + editedEvent.getId();
          } else if ("Start Date".equals(columnHeader)) {
              update = "update events set startdate = '" + dateFormatter.format(newValue) + "' where id = " + editedEvent.getId();
          } else if ("End Date".equals(columnHeader)) {
              update = "update events set enddate = '" + dateFormatter.format(newValue) + "' where id = " + editedEvent.getId();
          } else if ("Status".equals(columnHeader)) {
              update = "update events set status = '" + newValue + "' where id = " + editedEvent.getId();
          } else {
              log.error("Unrecognized value " + newValue + " encountered during event edit.");
              FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Event Save Failure:", "Apologies but we were unable to parse your entry " + newValue);
              FacesContext.getCurrentInstance().addMessage(null, message);
              return;
          }
          try {
              mysqlNamedParameterJdbcTemplate.update(update, new HashMap<String, String>());
          } catch (DuplicateKeyException e) { // There may be an event with the same name.
              FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Event Save Failure:",
                      "That name has already been used for an archived or logically deleted event. " + "Please use a different name for the new event to avoid confusion.");
              FacesContext.getCurrentInstance().addMessage(null, message);
              return;
          }
          log.info("Event " + eventBeforeEdit + " updated to " + editedEvent);
          loadEvents();
      }
      

      【讨论】:

        猜你喜欢
        • 2018-07-15
        • 1970-01-01
        • 1970-01-01
        • 2013-07-23
        • 2013-10-03
        • 2015-02-12
        • 2014-03-29
        • 1970-01-01
        • 2017-07-28
        相关资源
        最近更新 更多