我有一个数据表,它显示基于 List<> 的各种实体。当我选择一个单元格进行编辑时,我希望能够以某种方式获取实体以便更新它。当然还有 event.getRowIndex,然后我可以将其与 List<> 一起使用,但这并不总是很方便。是否有另一种方法可以从 CellEditEvent 获取实体?
3 回答
一种方法是以编程方式 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
并传递其他参数。否则显然会给出这个答案。
我一直在努力解决这个问题二,我不喜欢依赖 var 名称,所以我找到了这个解决方案:
public void onCellEdit(CellEditEvent event) {
Entity entity =(Entity)((DataTable)event.getComponent()).getRowData();
}
请注意,更新的实体可以直接合并到数据库中,您仍然可以获取旧值。PS:感谢@BalusC 所做的一切:)
我喜欢@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();
}