Jsf 使用primefaces进行部分处理时,datagrid的最后一个条目丢失

Jsf 使用primefaces进行部分处理时,datagrid的最后一个条目丢失,jsf,jsf-2,primefaces,Jsf,Jsf 2,Primefaces,我对部分处理有问题。(我使用primefaces 3.4.1。)我有一个列出服务的dataGrid,dataGrid的每一行都有一个commandButton“remove service”来删除服务。 我从支持bean中的服务列表中删除指定的服务,并在单击“删除服务”按钮时更新数据网格 另外,我在表单中有两个按钮; 第一个按钮“添加服务”,用于添加新服务;我将一个新对象添加到支持bean中的服务列表中,并在单击“添加服务”时更新数据网格。 第二个“保存”按钮用于保存所有服务。单击“保存按钮”时

我对部分处理有问题。(我使用primefaces 3.4.1。)我有一个列出服务的dataGrid,dataGrid的每一行都有一个commandButton“remove service”来删除服务。 我从支持bean中的服务列表中删除指定的服务,并在单击“删除服务”按钮时更新数据网格

另外,我在表单中有两个按钮; 第一个按钮“添加服务”,用于添加新服务;我将一个新对象添加到支持bean中的服务列表中,并在单击“添加服务”时更新数据网格。 第二个“保存”按钮用于保存所有服务。单击“保存按钮”时,服务列表将插入数据库

顺便说一句,我需要表单验证,因为我的服务对象中有必填字段。因此,应该在单击“添加服务”和“保存”时验证表单。但是,形式 单击“删除服务”按钮时不应进行验证。如果我对“删除服务”按钮使用“process=“@form”,则一切正常。我可以删除指定的服务 从备份bean和datagrid中的我的服务列表正确更新。但正如你所知,由于所有表单都经过处理,所以所有输入组件都经过验证。如果我使用'process=“@this”或'immediate=“true”作为“删除服务”按钮,我无法访问最后一个条目。我的意思是,我无法到达最后的服务。我想当我点击“删除服务”按钮时,它还没有被发布。 那么,我该怎么办?对这种情况有什么建议吗?先谢谢你

我的代码如下

<h:form id="formServicesTab">
        <h:panelGrid id="pnlSvcTab" columns="1" styleClass="valignTop" width="100%">
            <p:dataGrid id="dgServices" var="service"
                value="#{subMerchantOperations.subMerchantServices}"
                columns="1" width="100%" styleClass="valignTop"
                emptyMessage="#{messagebundle.submerc_grdlabel_no_service}" transient="true"
                rowIndexVar="index" >

                <p:toolbar>
                    <p:toolbarGroup align="left">
                        <p:commandButton id="btnRemoveSvc" onclick="loading.show();"
                            oncomplete="loading.hide();"
                            value="#{messagebundle.submerc_btn_delete_service}"                         
                            actionListener="#{subMerchantOperations.removeService}"                     
                            process="@form" update="@form">

                            <f:setPropertyActionListener target="#{subMerchantOperations.serviceRowIndex}" value="#{index}" />
                        </p:commandButton>                      
                    </p:toolbarGroup>
                </p:toolbar>

                <h:panelGrid columns="3" styleClass="valignTop" width="100%" bgcolor="F0F0F0">
                    <p:panel style="background:#F0F0F0;">
                        <h:panelGrid id="pnlDgSvc" columns="1" width="100%" style="height:100%">
                            <h:outputText value="#{messagebundle.submerc_label_svc_shortName}" />
                            <h:panelGrid columns="2">
                                <p:inputText id="txtSvcName" value="#{service.serviceName}"
                                    required="true" transient="true"
                                    requiredMessage="#{messagebundle.submerc_validation_msg_required}"
                                    converter="UpperCaseConverter" />
                                <p:message for="txtSvcName" display="text" />
                            </h:panelGrid>

                            <h:outputText value="#{messagebundle.submerc_label_svc_website}" />
                            <p:inputText value="#{service.serviceUrl}" transient="true"/>                           
                        </h:panelGrid>
                    </p:panel>

                    <p:panel style="background:#F0F0F0;">
                        <h:panelGrid columns="1" width="100%">
                            ..........
                        </h:panelGrid>
                    </p:panel>

                    <p:panel style="background:#F0F0F0;">
                        <h:panelGrid id="pgSvcFiles" columns="1" width="100%">
                            ...........      
                        </h:panelGrid>
                    </p:panel>
                </h:panelGrid>
            </p:dataGrid>
        </h:panelGrid>
        <p:toolbar style="background:white">
            <p:toolbarGroup align="left">               
                <p:commandButton id="btnAddNewSvc"                  
                    value="#{messagebundle.submerc_btn_addSvc}"                  
                    actionListener="#{subMerchantOperations.addNewService}"
                    process="@form" update="@form" />

                <p:commandButton id="btnSaveSubM"                   
                    value="#{messagebundle.submerc_btn_sendApproval}"                   
                    action="#{subMerchantOperations.saveServices}" 
                    process="@form" update="@form" />
            </p:toolbarGroup>
        </p:toolbar>
    </h:form>

@ManagedBean
@ViewScoped
public class SubMerchantOperations implements Serializable {
    private static final long serialVersionUID = 8556103952857187080L;  

    private List<Service> subMerchantServices = new ArrayList<Service>();
    private int serviceRowIndex;    

    // add new empty service to the service list
    public void addNewService() {
        try {
            Service svc = new Service();
            svc.setStartDate(new Date());
            getSubMerchantServices().add(svc);                      
        }
        catch(Exception ex) {
            if (logger.isEnabledFor(Level.ERROR)) {
                ...
            }           
        }       
    }

    // Remove the specified service using index parameter got from the datagrid
    public void removeService() {
        try {
            getSubMerchantServices().remove(serviceRowIndex);   
        }
        catch(Exception ex) {
            ... 
        }                               
    }

    // DB Operations
    public String saveSubMerchant() {       
        ...
    }

    public List<Service> getSubMerchantServices() {
        return subMerchantServices;
    }

    public void setSubMerchantServices(List<Service> subMerchantServices) {
        this.subMerchantServices = subMerchantServices;
    }
    public int getServiceRowIndex() {
        return serviceRowIndex;
    }

    public void setServiceRowIndex(int serviceRowIndex) {
        this.serviceRowIndex = serviceRowIndex;
    }
}

..........
...........      
@ManagedBean
@视域
公共类子类操作实现可序列化{
私有静态最终长serialVersionUID=855610395285718780L;
private List subMerchantServices=new ArrayList();
私有int-serviceRowIndex;
//将新的空服务添加到服务列表中
public void addNewService(){
试一试{
服务svc=新服务();
svc.setStartDate(新日期());
getSubMerchantServices().add(svc);
}
捕获(例外情况除外){
if(logger.isEnabledFor(Level.ERROR)){
...
}           
}       
}
//使用从datagrid获取的索引参数删除指定的服务
public void removeService(){
试一试{
getSubMerchantServices().remove(serviceRowIndex);
}
捕获(例外情况除外){
... 
}                               
}
//数据库操作
公共字符串saveSubMerchant(){
...
}
公共列表getSubMerchantServices(){
返回子目录服务;
}
公共无效设置子商品服务(列出子商品服务){
this.subMerchantServices=subMerchantServices;
}
public int getServiceRowIndex(){
返回serviceRowIndex;
}
公共void setServiceRowIndex(int-serviceRowIndex){
this.serviceRowIndex=serviceRowIndex;
}
}

我不知道
transient
属性在您的
上做了什么。我已经查看了Primefaces PDF文档的最新发布版本,但这不是一个有效属性

如果您发现基于FACLE的组件验证导致您的空表单在您的一个按钮上提交验证错误,您可以考虑在您的Bean方法中创建一个方法,该方法由您的提交方法调用,并验证bean上的元素状态。这是Primefaces的一种流行方法,因为与Seam不同,我们没有提供表单级验证

但是,一定要检查

可选地,您可以考虑注释注释POJO属性。


由于您使用的是收藏,请确保您的服务能够排除您的收藏中出现了一些不正常的情况并导致您的问题。

嘿,谢谢您的回答和建议。实际上,我在另一个验证问题中使用了transient属性。当验证失败时,即使表单被刷新,输入组件也会继续启动。我用transient属性防止了这个问题。顺便说一句,我会根据您的回复检查JSR303。再次感谢。。。