避免在记录编辑期间发生错误时更新数据表(JSF + Primefaces)
Avoid datatable update in case of error during record edition (JSF + Primefaces)
我在 JSF 2.1 + Primefaces 5.1 中有一个 Web 应用程序。我有一个包含 select 行的数据表。当我 select 一行并按下编辑按钮时,将打开一个对话框以允许用户编辑该记录的值。当用户按下对话框的保存按钮时,将调用一个过程来更新行并通过 Ajax 更新数据表。如果过程由于某些业务逻辑要求而失败,数据表不应更新,它应该保留该行的旧值。但是发生的是这些值在客户端得到更新,尽管在数据库中它们仍然保留旧的(正确的)值。刷新后,数据表显示旧值。
数据表和编辑按钮:
<h:form id="search_users_form_id">
<p:commandButton id="edit_user_button_id" value="#{msgs.edit}" disabled="#{usersBean.editUserButtonDisabled}" onclick="openDialog('edit_user_dlg')" update=":edit_user_form_id" actionListener="#{usersBean.populateDataForUserEdition}"/>
<p:dataTable id="users_table_id" var="user" value="#{usersBean.users}" rowKey="#{user.id}" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" selection="#{usersBean.selectedUser}" selectionMode="single" emptyMessage="#{msgs.no_records}" sortBy="#{user.id}"
sortOrder="ascending" rows="15">
<f:facet name="header">
#{msgs.users}
</f:facet>
<p:ajax event="rowSelect" listener="#{usersBean.onRowSelect}" update=":search_users_form_id:edit_user_button_id"/>
<p:ajax event="rowUnselect" listener="#{usersBean.onRowUnselect}" update=":search_users_form_id:edit_user_button_id"/>
<p:column headerText="#{msgs.id}" sortBy="#{user.id}" styleClass="centered-column">
#{user.id}
</p:column>
<p:column headerText="#{msgs.description}" sortBy="#{user.description}" styleClass="centered-column">
#{user.description}
</p:column>
<p:column headerText="#{msgs.password}" sortBy="#{user.password}" styleClass="centered-column">
#{user.password}
</p:column>
<p:column headerText="#{msgs.sending_system}" sortBy="#{user.playerIn.description}" styleClass="centered-column">
#{user.playerIn.description}
</p:column>
<p:column headerText="#{msgs.receiving_system}" sortBy="#{user.playerOut.description}" styleClass="centered-column">
#{user.playerOut.description}
</p:column>
<p:column headerText="#{msgs.active}" sortBy="#{user.active}" styleClass="centered-column">
<p:selectBooleanCheckbox value="#{user.active}" disabled="true"/>
</p:column>
<f:facet name="footer">
</f:facet>
</p:dataTable>
</h:form>
对话框:
<p:dialog modal="true" appendTo="@(body)" header="#{msgs.edit_user}" widgetVar="edit_user_dlg" closeOnEscape="true" resizable="false">
<h:form id="edit_user_form_id">
<h:panelGrid columns="3">
#{msgs.description}: <p:inputText value="#{usersBean.selectedUser.description}"/>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_description_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_description_tooltip_id" for="edit_user_description_tooltip_image_id" value="#{msgs.tooltip_users_description}"/>
</h:panelGroup>
#{msgs.password}:
<p:inputText value="#{usersBean.selectedUser.password}" maxlength="50"/>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_password_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_password_tooltip_id" for="edit_user_password_tooltip_image_id" value="#{msgs.tooltip_users_password}"/>
</h:panelGroup>
#{msgs.sending_system}:
<p:selectOneMenu styleClass="edit-user-selectonemenu" id="user_sending_system_id" value="#{usersBean.selectedUser.playerIn}" effectSpeed="fast" filter="true" filterMatchMode="contains" converter="#{playerConverter}">
<f:selectItem itemLabel="#{msgs.select_option}" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{usersBean.players}" var="player" itemValue="#{player}" itemLabel="#{player.description}"/>
</p:selectOneMenu>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_sending_system_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_sending_system_tooltip_id" for="edit_user_sending_system_tooltip_image_id" value="#{msgs.tooltip_users_sending_system}"/>
</h:panelGroup>
#{msgs.receiving_system}:
<p:selectOneMenu styleClass="edit-user-selectonemenu" id="user_receiving_system_id" value="#{usersBean.selectedUser.playerOut}" effectSpeed="fast" filter="true" filterMatchMode="contains" converter="#{playerConverter}">
<f:selectItem itemLabel="#{msgs.select_option}" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{usersBean.players}" var="player" itemValue="#{player}" itemLabel="#{player.description}"/>
</p:selectOneMenu>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_receiving_system_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_receiving_system_tooltip_id" for="edit_user_receiving_system_tooltip_image_id" value="#{msgs.tooltip_users_receiving_system}"/>
</h:panelGroup>
#{msgs.active}: <p:selectBooleanCheckbox id="edit_user_active_id" value="#{usersBean.selectedUser.active}"/>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_active_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_active_tooltip_id" for="edit_user_active_tooltip_image_id" value="#{msgs.tooltip_users_active}"/>
</h:panelGroup>
</h:panelGrid>
<h:panelGroup styleClass="edit-user-main-tooltip" layout="block">
<p:graphicImage id="edit_user_main_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_main_tooltip_id" for="edit_user_main_tooltip_image_id" value="#{msgs.tooltip_users_edit}"/>
</h:panelGroup>
<h:panelGroup styleClass="edit-user-dialog-buttons" layout="block">
<p:commandButton id="edit_user_save_button_id" value="#{msgs.save}" action="#{usersBean.updateUser}" onclick="closeDialog('edit_user_dlg')" update=":search_users_form_id:users_table_id"/>
<p:commandButton id="edit_user_cancel_button_id" value="#{msgs.cancel}" type="button" onclick="closeDialog('edit_user_dlg')"/>
</h:panelGroup>
</h:form>
</p:dialog>
更新方法只获取 selectedUser
对象并将其传递给存储过程。
public void updateUser() {
logger.entry();
this.selectedUser.setPlayerInId(this.selectedUser.getPlayerIn().getId());
this.selectedUser.setPlayerOutId(this.selectedUser.getPlayerOut().getId());
this.updateUser(this.selectedUser);
this.clearData();
logger.exit();
}
public void updateUser(DtoUser dtoUser) {
try {
logger.entry(dtoUser);
DtoBoUsers dtoBoUsers = dtoUser.toDtoBoUsers();
DtoTypeGenericResponse genericResponse = usersService.updateUser(backofficeUserBean.getCurrentSessionId(), dtoBoUsers);
if (genericResponse.getVResponse().equals(startupBean.getProperty(BackofficeProperties.RESPONSE_NOK))) {
BigDecimal id = this.selectedUser.getId();
logger.info(this.users.get(id.intValue()-1));
} else {
}
logger.exit(dtoUser);
} catch (BackofficeException | RuntimeException e) {
logger.error(ExceptionUtils.getStackTrace(e.fillInStackTrace()));
}
}
我该如何解决这个问题?我是否必须通过对数据库的查询强制重新填充数据表?或者我有更简洁的方法吗?
您基本上只想在业务服务调用成功后才执行update=":search_users_form_id:users_table_id"
。您可以通过从 <p:commandButton>
中删除该属性并在 RequestContext#update()
.
的帮助下在操作方法中以编程方式执行它来实现。
try {
// ...
RequestContext.getCurrentInstance().update("search_users_form_id:users_table_id");
}
catch (Exception e) {
// ...
}
我在 JSF 2.1 + Primefaces 5.1 中有一个 Web 应用程序。我有一个包含 select 行的数据表。当我 select 一行并按下编辑按钮时,将打开一个对话框以允许用户编辑该记录的值。当用户按下对话框的保存按钮时,将调用一个过程来更新行并通过 Ajax 更新数据表。如果过程由于某些业务逻辑要求而失败,数据表不应更新,它应该保留该行的旧值。但是发生的是这些值在客户端得到更新,尽管在数据库中它们仍然保留旧的(正确的)值。刷新后,数据表显示旧值。
数据表和编辑按钮:
<h:form id="search_users_form_id">
<p:commandButton id="edit_user_button_id" value="#{msgs.edit}" disabled="#{usersBean.editUserButtonDisabled}" onclick="openDialog('edit_user_dlg')" update=":edit_user_form_id" actionListener="#{usersBean.populateDataForUserEdition}"/>
<p:dataTable id="users_table_id" var="user" value="#{usersBean.users}" rowKey="#{user.id}" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" selection="#{usersBean.selectedUser}" selectionMode="single" emptyMessage="#{msgs.no_records}" sortBy="#{user.id}"
sortOrder="ascending" rows="15">
<f:facet name="header">
#{msgs.users}
</f:facet>
<p:ajax event="rowSelect" listener="#{usersBean.onRowSelect}" update=":search_users_form_id:edit_user_button_id"/>
<p:ajax event="rowUnselect" listener="#{usersBean.onRowUnselect}" update=":search_users_form_id:edit_user_button_id"/>
<p:column headerText="#{msgs.id}" sortBy="#{user.id}" styleClass="centered-column">
#{user.id}
</p:column>
<p:column headerText="#{msgs.description}" sortBy="#{user.description}" styleClass="centered-column">
#{user.description}
</p:column>
<p:column headerText="#{msgs.password}" sortBy="#{user.password}" styleClass="centered-column">
#{user.password}
</p:column>
<p:column headerText="#{msgs.sending_system}" sortBy="#{user.playerIn.description}" styleClass="centered-column">
#{user.playerIn.description}
</p:column>
<p:column headerText="#{msgs.receiving_system}" sortBy="#{user.playerOut.description}" styleClass="centered-column">
#{user.playerOut.description}
</p:column>
<p:column headerText="#{msgs.active}" sortBy="#{user.active}" styleClass="centered-column">
<p:selectBooleanCheckbox value="#{user.active}" disabled="true"/>
</p:column>
<f:facet name="footer">
</f:facet>
</p:dataTable>
</h:form>
对话框:
<p:dialog modal="true" appendTo="@(body)" header="#{msgs.edit_user}" widgetVar="edit_user_dlg" closeOnEscape="true" resizable="false">
<h:form id="edit_user_form_id">
<h:panelGrid columns="3">
#{msgs.description}: <p:inputText value="#{usersBean.selectedUser.description}"/>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_description_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_description_tooltip_id" for="edit_user_description_tooltip_image_id" value="#{msgs.tooltip_users_description}"/>
</h:panelGroup>
#{msgs.password}:
<p:inputText value="#{usersBean.selectedUser.password}" maxlength="50"/>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_password_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_password_tooltip_id" for="edit_user_password_tooltip_image_id" value="#{msgs.tooltip_users_password}"/>
</h:panelGroup>
#{msgs.sending_system}:
<p:selectOneMenu styleClass="edit-user-selectonemenu" id="user_sending_system_id" value="#{usersBean.selectedUser.playerIn}" effectSpeed="fast" filter="true" filterMatchMode="contains" converter="#{playerConverter}">
<f:selectItem itemLabel="#{msgs.select_option}" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{usersBean.players}" var="player" itemValue="#{player}" itemLabel="#{player.description}"/>
</p:selectOneMenu>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_sending_system_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_sending_system_tooltip_id" for="edit_user_sending_system_tooltip_image_id" value="#{msgs.tooltip_users_sending_system}"/>
</h:panelGroup>
#{msgs.receiving_system}:
<p:selectOneMenu styleClass="edit-user-selectonemenu" id="user_receiving_system_id" value="#{usersBean.selectedUser.playerOut}" effectSpeed="fast" filter="true" filterMatchMode="contains" converter="#{playerConverter}">
<f:selectItem itemLabel="#{msgs.select_option}" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{usersBean.players}" var="player" itemValue="#{player}" itemLabel="#{player.description}"/>
</p:selectOneMenu>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_receiving_system_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_receiving_system_tooltip_id" for="edit_user_receiving_system_tooltip_image_id" value="#{msgs.tooltip_users_receiving_system}"/>
</h:panelGroup>
#{msgs.active}: <p:selectBooleanCheckbox id="edit_user_active_id" value="#{usersBean.selectedUser.active}"/>
<h:panelGroup layout="block">
<p:graphicImage id="edit_user_active_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_active_tooltip_id" for="edit_user_active_tooltip_image_id" value="#{msgs.tooltip_users_active}"/>
</h:panelGroup>
</h:panelGrid>
<h:panelGroup styleClass="edit-user-main-tooltip" layout="block">
<p:graphicImage id="edit_user_main_tooltip_image_id" library="images" name="icon-tooltip.jpg"/>
<p:tooltip id="edit_user_main_tooltip_id" for="edit_user_main_tooltip_image_id" value="#{msgs.tooltip_users_edit}"/>
</h:panelGroup>
<h:panelGroup styleClass="edit-user-dialog-buttons" layout="block">
<p:commandButton id="edit_user_save_button_id" value="#{msgs.save}" action="#{usersBean.updateUser}" onclick="closeDialog('edit_user_dlg')" update=":search_users_form_id:users_table_id"/>
<p:commandButton id="edit_user_cancel_button_id" value="#{msgs.cancel}" type="button" onclick="closeDialog('edit_user_dlg')"/>
</h:panelGroup>
</h:form>
</p:dialog>
更新方法只获取 selectedUser
对象并将其传递给存储过程。
public void updateUser() {
logger.entry();
this.selectedUser.setPlayerInId(this.selectedUser.getPlayerIn().getId());
this.selectedUser.setPlayerOutId(this.selectedUser.getPlayerOut().getId());
this.updateUser(this.selectedUser);
this.clearData();
logger.exit();
}
public void updateUser(DtoUser dtoUser) {
try {
logger.entry(dtoUser);
DtoBoUsers dtoBoUsers = dtoUser.toDtoBoUsers();
DtoTypeGenericResponse genericResponse = usersService.updateUser(backofficeUserBean.getCurrentSessionId(), dtoBoUsers);
if (genericResponse.getVResponse().equals(startupBean.getProperty(BackofficeProperties.RESPONSE_NOK))) {
BigDecimal id = this.selectedUser.getId();
logger.info(this.users.get(id.intValue()-1));
} else {
}
logger.exit(dtoUser);
} catch (BackofficeException | RuntimeException e) {
logger.error(ExceptionUtils.getStackTrace(e.fillInStackTrace()));
}
}
我该如何解决这个问题?我是否必须通过对数据库的查询强制重新填充数据表?或者我有更简洁的方法吗?
您基本上只想在业务服务调用成功后才执行update=":search_users_form_id:users_table_id"
。您可以通过从 <p:commandButton>
中删除该属性并在 RequestContext#update()
.
try {
// ...
RequestContext.getCurrentInstance().update("search_users_form_id:users_table_id");
}
catch (Exception e) {
// ...
}