简体   繁体   English

在PrimeFaces中更改每页的行值后,数据表的奇怪行为

[英]Strange behaviour of datatable after changing rows per page value in PrimeFaces

When I edit a row using PrimeFaces' in-place editing feature for a table, the changes don't seem to be applied. 当我使用PrimeFaces的表的就地编辑功能编辑一行时,似乎没有应用更改。

Here is my code: 这是我的代码:

properties.xhtml properties.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"  
      xmlns:c="http://java.sun.com/jsp/jstl/core">

    <f:event type="javax.faces.event.PreRenderViewEvent" listener="${propertyManagedBean.preRenderView}"/>

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Properties</title>
    </h:head>

    <h:body> 
            <div id="content" class="left_content">
                <h:form>
                    <p:dataTable id="tbl" var="property" value="#{propertyManagedBean.properties}" paginator="true" rows="10" rowsPerPageTemplate="5,10,20">  

                        <p:ajax event="rowEdit" update="@this" listener="#{propertyManagedBean.propertyRowEdit}"/>

                        <f:facet name="header">  
                            Properties Manager  
                        </f:facet>   

                        <p:column headerText="Key" >                               
                            <h:outputText value="#{property.propKey}" />  
                        </p:column>  

                        <p:column headerText="Value">  
                            <p:cellEditor>
                                <f:facet name="output">  
                                    <h:outputText value="#{property.propValue}" /> 
                                </f:facet>
                                <f:facet name="input">  
                                    <p:inputText value="#{property.propValue}" style="width:100%"/>  
                                </f:facet>  
                            </p:cellEditor> 
                        </p:column>  

                        <p:column headerText="Options" style="width:15px">  
                            <p:rowEditor />  
                        </p:column> 
                    </p:dataTable>     
                </h:form>
            </div>
    </h:body>   
</html>

PropertyManagedBean.java PropertyManagedBean.java

@ManagedBean
@SessionScoped
public class PropertyManagedBean {

    private PropertyJpaController controller;
    private List<Property> properties;

    /** Creates a new instance of propertyManagedBean */
    public PropertyManagedBean() {
        controller = new PropertyJpaController();
        extractProperties();
    }

    public void propertyRowEdit(RowEditEvent event) {
        Property prop = (Property) event.getObject();
        try {
            controller.update(prop);         
        } catch (Exception ex) {
            //TODO: Customize work with exceptions
        }
        extractProperties();
    }

    public List<Property> getProperties() {
        return properties;
    }

    public void preRenderView() {
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
    }

    private void extractProperties() {
         properties = controller.findPropertyEntities();
    }
}

The problem happened after editing a property in a row on the page. 在页面上连续编辑属性后,发生了问题。 After changing this row, I get the old values of the properties in my table. 更改此行后,我在表中获得了属性的旧值。

My guess is that there's an exception happening in controller.update(prop) that you're not showing, so the update doesn't actually happen. 我的猜测是在controller.update(prop)中发生了一个您未显示的异常,因此该更新实际上并未发生。

If I quickly test your code with a mock Service, it works as expected. 如果我使用模拟服务快速测试您的代码,它将按预期工作。

Facelet: 小面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"  
>

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Properties</title>
    </h:head>

    <h:body> 
         <h:form>
             <p:dataTable id="tbl" value="#{propertyManagedBean.properties}" var="property" paginator="true" rows="10" rowsPerPageTemplate="5,10,20">  

                 <p:ajax event="rowEdit" update="@this" listener="#{propertyManagedBean.propertyRowEdit}"/>

                 <f:facet name="header">  
                     Properties Manager  
                 </f:facet>   

                 <p:column headerText="Key" >                               
                     #{property.propKey}  
                 </p:column>  

                 <p:column headerText="Value">  
                     <p:cellEditor>
                         <f:facet name="output">  
                             #{property.propValue} 
                         </f:facet>
                         <f:facet name="input">  
                             <p:inputText value="#{property.propValue}" style="width:100%"/>  
                         </f:facet>  
                     </p:cellEditor> 
                 </p:column>  

                 <p:column headerText="Options" style="width:15px">  
                     <p:rowEditor />  
                 </p:column> 
             </p:dataTable> 
         </h:form>
    </h:body>   
</html>

Backing bean: 后备豆:

@ManagedBean
@SessionScoped
public class PropertyManagedBean {

    private PropertyJpaController controller;
    private List<Property> properties;

    public PropertyManagedBean() {
        controller = new PropertyJpaController();
        extractProperties();
    }

    public void propertyRowEdit(RowEditEvent event) {
        Property property = (Property) event.getObject();
        try {
            controller.update(property);
        } catch (Exception ex) {
            // TODO: Customize work with exceptions
        }
        extractProperties();
    }

    public List<Property> getProperties() {
        return properties;
    }

    private void extractProperties() {
        properties = controller.findPropertyEntities();
    }
}

Mock Service: 模拟服务:

public class PropertyJpaController {

    private List<Property> properties = new ArrayList<Property>();

    {
        properties.add(new Property("KeyA", "ValueA"));
        properties.add(new Property("KeyB", "ValueB"));
    }

    public List<Property> findPropertyEntities() {
        // Copy list and entries to prevent direct in-memory updating
        List<Property> newList = new ArrayList<Property>();
        for (Property property : properties) {
            newList.add(new Property(property.getPropKey(), property.getPropValue()));
        }

        return newList;
    }

    public void update(Property updatedProperty) {
        for (Property property : properties) {
            if (property.getPropKey().equals(updatedProperty.getPropKey())) {
                property.setPropValue(updatedProperty.getPropValue());
            }
        }
    }
}

Mock Model: 模拟模型:

public class Property {

    private String propKey;
    private String propValue;

    public Property(String propKey, String propValue) {
        this.propKey = propKey;
        this.propValue = propValue;
    }

    public String getPropKey() {
        return propKey;
    }

    public void setPropKey(String propKey) {
        this.propKey = propKey;
    }

    public String getPropValue() {
        return propValue;
    }

    public void setPropValue(String propValue) {
        this.propValue = propValue;
    }
}

Note that the preRenderView event listener was rather unnecessary. 请注意, preRenderView事件侦听器是不必要的。 Also, normally you wouldn't make the backing bean @SessionScoped , but for the mock case it's handy for testing that the changes actually did 'persist'. 同样,通常您不会制作支持bean @SessionScoped ,但是对于模拟情况,它很容易测试更改是否确实“持久”。

This was tested btw with PrimeFaces 3rc2 on JBoss AS 7. 已在JBoss AS 7上使用PrimeFaces 3rc2进行了测试。

The Primefaces dataTable has an attribute called rowEditListener . Primefaces数据表具有一个名为rowEditListener的属性。 You should use this attribute instead of using the internal <p:ajax> component. 您应该使用此属性,而不要使用内部的<p:ajax>组件。 This will likely solve your update problem. 这可能会解决您的更新问题。

<p:dataTable ... rowEditListener="#{propertyManagedBean.propertyRowEdit}">

EDIT: It appears that this attribute no longer exists in Primefaces 3.0 per the user guide. 编辑:根据用户指南,此属性似乎在Primefaces 3.0中不再存在。 Disregard my answer, but I will leave it as this still applies to Primefaces 2.2.1 and could benefit somebody else. 忽略我的答案,但我将保留它,因为这仍然适用于Primefaces 2.2.1,并可能使其他人受益。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM