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

时间:2011-12-28 10:02:25

标签: java jsf primefaces

当我使用表格的PrimeFaces就地编辑功能编辑行时,似乎没有应用更改。

这是我的代码:

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

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

在页面上的一行中编辑属性后发生问题。更改此行后,我会在表格中获取属性的旧值。

2 个答案:

答案 0 :(得分:3)

我的猜测是controller.update(prop)发生了一个您未展示的异常,因此更新实际上并未发生。

如果我使用模拟服务快速测试您的代码,它会按预期工作。

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

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

模拟服务:

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

模拟模型:

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

请注意,preRenderView事件侦听器是不必要的。此外,通常你不会制作支持bean @SessionScoped,但对于模拟案例,它可以方便地测试更改实际上是'持久'。

这是在JBoss AS 7上使用PrimeFaces 3rc2测试的。

答案 1 :(得分:0)

Primefaces dataTable有一个名为rowEditListener的属性。您应该使用此属性而不是使用内部<p:ajax>组件。这可能会解决您的更新问题。

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

编辑:根据用户指南,Primefaces 3.0中似乎不再存在此属性。无视我的回答,但我会离开它,因为这仍然适用于Primefaces 2.2.1,并可能使其他人受益。