避免在记录版本中发生错误的数据更新(JSF + Primefaces) [英] Avoid datatable update in case of error during record edition (JSF + Primefaces)

查看:124
本文介绍了避免在记录版本中发生错误的数据更新(JSF + Primefaces)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JSF 2.1 + Primefaces 5.1中有一个网络应用程序。我有一个可选行的数据。当我选择一行并按编辑按钮时,会打开一个对话框,允许用户编辑该记录的值。当用户按下对话框的保存按钮时,会调用一个过程来更新行并通过Ajax更新数据。如果程序由于某些业务逻辑要求而失败,则datatable不应更新,因此应保留该行的旧值。但是发生的情况是,值在客户端更新,尽管在数据库中它们仍然是旧的(和正确的)值。刷新后,datatable显示旧的值。



数据和编辑按钮:

 < h:form id =search_users_form_id> 
< p:commandButton id =edit_user_button_idvalue =#{msgs.edit}disabled =#{usersBean.editUserButtonDisabled}onclick =openDialog('edit_user_dlg')update =:edit_user_form_id actionListener =#{usersBean.populateDataForUserEdition}/>

< p:dataTable id =users_table_idvar =uservalue =#{usersBean.users}rowKey =#{user.id}paginator =true
paginatorTemplate ={CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}
rowsPerPageTemplate =5,10,15selection =#{usersBean.selectedUser} selectionMode =singleemptyMessage =#{msgs.no_records}sortBy =#{user.id}
sortOrder =ascendingrows =15>
< f:facet name =header>
#{msgs.users}
< / f:facet>
< p:ajax event =rowSelectlistener =#{usersBean.onRowSelect}update =:search_users_form_id:edit_user_button_id/>
< p:ajax event =rowUnselectlistener =#{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 =trueappendTo =@(body)header =#{msgs.edit_user}widgetVar =edit_user_dlgcloseOnEscape =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_idlibrary =imagesname =icon-tooltip.jpg/>
< p:tooltip id =edit_user_description_tooltip_idfor =edit_user_description_tooltip_image_idvalue =#{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_idlibrary =imagesname =icon-tooltip.jpg/>
< p:tooltip id =edit_user_password_tooltip_idfor =edit_user_password_tooltip_image_idvalue =#{msgs.tooltip_users_password}/>
< / h:panelGroup>

#{msgs.sending_system}:
< p:selectOneMenu styleClass =edit-user-selectonemenuid =user_sending_system_idvalue =#{usersBean.selectedUser.playerIn} effectSpeed =fastfilter =truefilterMatchMode =containsconverter =#{playerConverter}>
< f:selectItem itemLabel =#{msgs.select_option}itemValue =#{null}noSelectionOption =true/>
< f:selectItems value =#{usersBean.players}var =playeritemValue =#{player}itemLabel =#{player.description}/>
< / p:selectOneMenu>
< h:panelGroup layout =block>
< p:graphicImage id =edit_user_sending_system_tooltip_image_idlibrary =imagesname =icon-tooltip.jpg/>
< p:tooltip id =edit_user_sending_system_tooltip_idfor =edit_user_sending_system_tooltip_image_idvalue =#{msgs.tooltip_users_sending_system}/>
< / h:panelGroup>

#{msgs.receiving_system}:
< p:selectOneMenu styleClass =edit-user-selectonemenuid =user_receiving_system_idvalue =#{usersBean.selectedUser.playerOut} effectSpeed =fastfilter =truefilterMatchMode =containsconverter =#{playerConverter}>
< f:selectItem itemLabel =#{msgs.select_option}itemValue =#{null}noSelectionOption =true/>
< f:selectItems value =#{usersBean.players}var =playeritemValue =#{player}itemLabel =#{player.description}/>
< / p:selectOneMenu>
< h:panelGroup layout =block>
< p:graphicImage id =edit_user_receiving_system_tooltip_image_idlibrary =imagesname =icon-tooltip.jpg/>
< p:tooltip id =edit_user_receiving_system_tooltip_idfor =edit_user_receiving_system_tooltip_image_idvalue =#{msgs.tooltip_users_receiving_system}/>
< / h:panelGroup>

#{msgs.active}:< p:selectBooleanCheckbox id =edit_user_active_idvalue =#{usersBean.selectedUser.active}/>
< h:panelGroup layout =block>
< p:graphicImage id =edit_user_active_tooltip_image_idlibrary =imagesname =icon-tooltip.jpg/>
< p:tooltip id =edit_user_active_tooltip_idfor =edit_user_active_tooltip_image_idvalue =#{msgs.tooltip_users_active}/>
< / h:panelGroup>
< / h:panelGrid>
< h:panelGroup styleClass =edit-user-main-tooltiplayout =block>
< p:graphicImage id =edit_user_main_tooltip_image_idlibrary =imagesname =icon-tooltip.jpg/>
< p:tooltip id =edit_user_main_tooltip_idfor =edit_user_main_tooltip_image_idvalue =#{msgs.tooltip_users_edit}/>
< / h:panelGroup>
< h:panelGroup styleClass =edit-user-dialog-buttonslayout =block>
< p:commandButton id =edit_user_save_button_idvalue =#{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_idvalue =#{msgs.cancel}type =buttononclick =closeDialog('edit_user_dlg')/>
< / h:panelGroup>
< / h:form>
< / p:dialog>

更新方法只需要 selectedUser 对象并将其传递给存储过程。

  public void updateUser(){
logger 。条目();
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()));
}
}

我该如何解决?我必须强制重新填充datatable,再次查询DB吗?或者我有一个更干净的方法吗?

解决方案

你基本上想执行 update = :search_users_form_id:users_table_id只有在业务呼叫成功的情况下。您可以通过从< p:commandButton> 中删除​​该属性,并通过 RequestContext#update()

  try {
// ...
RequestContext。 getCurrentInstance()。update(search_users_form_id:users_table_id);
}
catch(异常e){
// ...
}


I have a web-app in JSF 2.1 + Primefaces 5.1. I have a datatable with selectable rows. When I select a row and press the Edit button, a dialog opens to allow the user to edit the values of that record. When the user presses the dialog's Save button, a procedure is called to update the row and update the datatable via Ajax. If the procedure fails due to some business logic requirements, the datatable shouldn't update, it should keep the old values for that row. But what happens is that the values get updated on client-side, although in the DB they remain with the old (and correct) values. After a refresh, the datatable shows the old values.

The datatable and the edit button:

<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>

The dialog:

<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>

The update method just takes the selectedUser object and passes it to a stored procedure.

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()));           
        } 
    }

How can I solve this? Do I have to force a repopulate the datatable again with a query to the DB? Or do I have a cleaner way of doing it?

解决方案

You basically want to perform update=":search_users_form_id:users_table_id" only when the business service call has succeeded. You could achieve that by removing that attribute from the <p:commandButton> and performing it programmatically in the action method with help of RequestContext#update().

try {
    // ...
    RequestContext.getCurrentInstance().update("search_users_form_id:users_table_id");
}
catch (Exception e) {
    // ...
}

这篇关于避免在记录版本中发生错误的数据更新(JSF + Primefaces)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆