0

我正在使用 primefaces 数据表和 RowEditor 创建一个 JSF 2.2 CRUD 页面。

我的问题在于编辑行。我使用 2 个不同的侦听器来比较编辑前后的记录(以确保有任何修改等)

为此,只要用户单击铅笔图标,我就使用 RowEditInit 来获取初始值。

用户更改行数据后,我使用 RowEdit 事件进行一些检查并比较前后值,但我的初始对象最终获得了用户在单击保存后键入的相同值。

代码

 <h:form id="edicao" prependId="false">
            <p:growl id="msgs" showDetail="true" globalOnly="true" escape="true"/>
            <p:dataTable id="dataTable" var="linha"  value="#{perfilMB.listaPerfilEntities}" 
                         editable="true" draggableColumns="true" rendered="#{not empty perfilMB.listaPerfilEntities}"
                         widgetVar="tablePerfil" filteredValue="#{perfilMB.filteredPerfilEntities}"
                         emptyMessage="Não existem registros." resizableColumns="true" styleClass="datatable_cadastro" >

                <f:facet name="header">
                    <span class="titulo_datatable" >Tabela Perfil</span>
                    <p:commandButton id="toggler" type="button" value="Colunas" />
                    <p:columnToggler datasource="dataTable" trigger="toggler" />
                </f:facet>

                <p:ajax event="rowEdit" listener="#{perfilMB.onRowEdit}" update=":edicao:msgs" />
                <p:ajax event="rowEditCancel" listener="#{perfilMB.onRowCancel}" update=":edicao:msgs" />
                <p:ajax event="rowEditInit" listener="#{perfilMB.rowEditInit}" />   

                <p:column headerText="ID" sortBy="#{linha.id}"
                    style="width:50px;">
                    <p:outputLabel value="#{linha.id}" style="width:100%" />
                </p:column>
                <p:column headerText="NOME" filterBy="#{linha.perfil}"
                    filterMatchMode="contains" sortBy="#{linha.perfil}"
                    style="width:100%;">
                    <p:cellEditor>
                        <f:facet name="output">
                            <h:outputText value="#{linha.perfil}" />
                        </f:facet>
                        <f:facet name="input">
                            <p:inputTextarea value="#{linha.perfil}" id="nome"
                                update=":edicao" style="width:100%" />
                        </f:facet>
                    </p:cellEditor>
                </p:column>
                <p:column headerText="DETALHAMENTO"
                    style="width:100%;"
                    sortBy="#{linha.descritivo}" filterBy="#{linha.descritivo}"
                    filterMatchMode="contains">
                    <p:cellEditor>
                        <f:facet name="output">
                            <h:outputText value="#{linha.descritivo}" />
                        </f:facet>
                        <f:facet name="input">
                            <p:inputTextarea value="#{linha.descritivo}"
                                id="detalhamento" update=":edicao" />
                        </f:facet>
                    </p:cellEditor>
                </p:column>

                <p:column headerText="ATIVO" style="width:150px;" filterBy="#{linha.ativo}" filterMatchMode="equals">
                        <f:facet name="filter">
                            <p:selectOneMenu onchange="PF('tablePerfil').filter()" >
                                <f:converter converterId="javax.faces.Character"/>
                                <f:selectItem itemLabel="TODOS" itemValue=""/>
                                <f:selectItem itemLabel="ATIVO" itemValue="T"/>
                                <f:selectItem itemLabel="INATIVO" itemValue="F"/>
                            </p:selectOneMenu>
                        </f:facet>
                        <p:cellEditor>
                            <f:facet name="output">
                                <p:selectBooleanCheckbox value="#{perfilMB.charToBool(linha.ativo)}" disabled="true"/> 
                            </f:facet>
                            <f:facet name="input">
                                <p:selectBooleanCheckbox value="#{perfilMB.ativo}" id="ativo" immediate="true" update=":edicao" style="width:100%"/>
                            </f:facet>

                        </p:cellEditor> 
                    </p:column>

                <p:column headerText="!" style="width:40px">
                    <p:rowEditor />
                </p:column>
                <p:column headerText="X" style="width:40px">
                    <p:commandLink styleClass="ui-icon ui-icon-trash" action="#{perfilMB.preparaParaDeletar(linha)}" update=":confirmacao_exclusao" oncomplete="PF('confirmacao').show()" />
                </p:column>

            </p:dataTable>  

        </h:form>

@ViewScoped

进口

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.RowEditEvent;

工作流程:

1 - 用户单击编辑行按钮,触发 RowEditInit。

2 - 对象 perfilAntes 从该行获取初始值。

RowEditInit 方法

public void rowEditInit(RowEditEvent event) {
    Object value = event.getObject();
    perfilAntes = new PerfilEntity();
    perfilAntes = (PerfilEntity) value;
}

3 - 用户完成数据编辑后,点击保存,调用 RowEdit 方法。

4 - 新对象名称 perfilTela 获取用户输入的新值。

5 - 调用将两个对象相互比较的 validaOnRowEdit 方法。

行编辑方法

public void onRowEdit(RowEditEvent event) {

    context = FacesContext.getCurrentInstance();

    Object value = event.getObject();

    PerfilEntity perfilTela = (PerfilEntity) value;

    if(perfilTela.getId() != null){

        /* Calls the validation method  */
        boolean validado = validaOnRowEdit(perfilTela);

         /* if its all Good, saves the data on database*/
        if(validado){
        /*removed code*/
        }           
}

数据验证方法

此方法将两个对象 PerfilAntes(初始值)与 PerfilTela(用户键入的值)进行比较。

当我检查对象值时,PerfilAntes 对象失去了它的初始值,它等于 PerfilTela 对象!

public boolean validaOnRowEdit(PerfilEntity perfilTela){
        if(perfilAntes.getId() != null){
            if( perfilTela.getPerfil().trim() != null && perfilTela.getDescritivo().trim() != null ){
                if( perfilTela.getPerfil().equals(perfilAntes.getPerfil() ) 
                    && perfilTela.getDescritivo().equals(perfilAntes.getDescritivo() ) 
                    && perfilTela.getAtivo() == perfilAntes.getAtivo() ){

                    perfilTela = perfilAntes;
                    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Changes Canceled" ,"There was no changes in row <br/><b>Case Insensitive<b/>" ));
                    return false;
                } else {
                    return true;
                }
            } else {
                perfilTela = perfilAntes;
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Changes canceled" ,"No field can be empty or contain spaces" ));
                return false;
            }
        }
    }
4

2 回答 2

0

尝试使用 @SessionScoped bean 看看会发生什么,您的代码似乎没问题。

于 2015-10-28T18:36:22.583 回答
0

我发现了问题所在。

使用 Object 变量时,您可以像这样创建对象并设置值:

Object object1 = new Object();
Object object2 = new Object();
object1 = object2;

对象变量不会将对象值保存在这些变量中,而是仅保存堆栈内存中变量之间的引用。

所以当我设置:object1 = object2;

object1 正在接收指向在 object2 上设置的对象的“指针”,如果我使用这些变量中的任何一个来编辑其中一个属性,则两者都将被更改,因为它只包含一个链接。

并且因为我设置了object1 = object2,所以之前存在于Heap上的object1上的链接对象不能再使用了,会被Garbage Collector清理掉。

所以我最终使用设置器设置值。

于 2015-12-01T18:10:14.460 回答