2013-06-05 42 views
0

我使用PrimeFaces 3.1,我必须在datable中选择一行。 我在Primefaces展示中使用了这个例子来做到这一点,但它只在我的支持bean处于作用域会话中,而不是在视图中时才起作用,这意味着当用户回来时,我必须做一些额外的工作来移除它页面,我的代码有什么问题? 我控制器(在要求范围内):Primefaces数据表选择行和范围

@ManagedBean 
@RequestScoped 
public class Ctrlr implements Serializable{ 
    @ManagedProperty(value = "#{myDataModel}") 
    private MyDataModel dataModel; 
    ... 
    public void onSelectRow() { 
    //do something 
    } 
} 

的backingBean(我不得不使用会话范围有一个正确的工作):

@ManagedBean 
@ViewScoped 
public class MyDataModel extends ListDataModel<Bean> implements SelectableDataModel<Bean>, Serializable { 
    ... 
} 

我的XHTML页面:

<p:dataTable var="bean" 
     id="tableResults" 
     selectionMode="single" 
     selection="#{ctrlr.selectedBean}" 
     value="#{myDataModel}" 
     rowKey="#{bean.id}"> 
     <p:ajax event="rowSelect" 
      listener="#{ctrlr.onSelectRow()}" 
      update=":searchForm:details:detail"/> 
     ... 

我检查了调试,似乎每次控制器重建(每个请求),注入的属性是一个新的,而不是从viewScope重新注入。

如果有人可以帮我避免使用会话范围?

+0

它不需要是scopeview。 – Makky

+0

发布完整的代码,因为我们无法看到最新的错误。 – Makky

+0

我试图只把我的代码的相关部分,但如果你认为缺少某些东西,告诉我,我会添加它。 – 893

回答

2

我认为你可能会太多地跟随教程。

参见下面的简单工作实例:

Car类

package test_war.test_war; 

public class Car { 

    private String name; 
    private Double price; 
    private int year; 

    public String getName() { 
     return name; 
    } 

    public Car(String name, Double price, int year) { 
     super(); 
     this.name = name; 
     this.price = price; 
     this.year = year; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Double getPrice() { 
     return price; 
    } 

    public void setPrice(Double price) { 
     this.price = price; 
    } 

    public int getYear() { 
     return year; 
    } 

    public void setYear(int year) { 
     this.year = year; 
    } 

} 

BackBean(Viewscoped)

package test_war.test_war; 

import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.List; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 

@ManagedBean(name = "testBean") 
@ViewScoped 
public class TestBean implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private List<Car> cars; 
    private Car selectedCar; 

    public Car getSelectedCar() { 
     return selectedCar; 
    } 

    public void setSelectedCar(Car selectedCar) { 
     this.selectedCar = selectedCar; 
    } 

    @PostConstruct 
    public void init() { 
     cars = new ArrayList<Car>(); 
     cars.add(new Car("test1", 111.11, 2011)); 
     cars.add(new Car("test2", 711.11, 2012)); 
     cars.add(new Car("test3", 511.11, 2001)); 
     cars.add(new Car("test4", 411.11, 2000)); 
    } 

    public List<Car> getCars() { 
     return cars; 
    } 

    public void setCars(List<Car> cars) { 
     this.cars = cars; 
    } 

    } 

视图(main.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:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:p="http://primefaces.org/ui"> 

<h:head> 
    <title>A Simple JavaServer Faces 2.0 View</title> 
</h:head> 
<h:body> 
    <h:form id="form"> 
     <p:dataTable id="cars" var="car" value="#{testBean.cars}" 
      rowKey="#{car.name}" selection="#{testBean.selectedCar}" 
      selectionMode="single"> 

      <f:facet name="header"> 
      Click "View" button after selecting a row to see details 
     </f:facet> 

      <p:column headerText="Name"> 
      #{car.name} 
     </p:column> 

      <p:column headerText="Year"> 
      #{car.year} 
     </p:column> 

      <p:column headerText="Price"> 
      #{car.price} 
     </p:column> 



      <f:facet name="footer"> 
       <p:commandButton id="viewButton" value="View" icon="ui-icon-search" 
        update=":form:display" oncomplete="carDialog.show()" /> 
      </f:facet> 

     </p:dataTable> 

     <p:dialog id="dialog" header="Car Detail" widgetVar="carDialog" 
      resizable="false" width="200" showEffect="clip" hideEffect="fold"> 

      <h:panelGrid id="display" columns="2" cellpadding="4"> 



       <h:outputText value="Name:" /> 
       <h:outputText value="#{testBean.selectedCar.name}" /> 

       <h:outputText value="Year:" /> 
       <h:outputText value="#{testBean.selectedCar.year}" /> 

       <h:outputText value="Price:" /> 
       <h:outputText value="#{testBean.selectedCar.price}" /> 
      </h:panelGrid> 
     </p:dialog> 

    </h:form> 
</h:body> 
</html> 

输出

Output

如果您需要整个项目作为WAR/Zip文件让我KNW。

+0

但根据viewScope只调用一次@postContruct(只要您在浏览器窗口/选项卡中与相同的JSF视图进行交互,此范围内的bean就会处于活动状态,它会根据HTTP请求创建并获取一旦你回传到不同的视图就会被破坏)。 – 893

+0

好,然后把所有东西都放在结构中。 – Makky

+0

为什么我必须把所有东西都放在构造函数中?因为相同的代码工作正常,只需将后台bean放在会话中而不是视图范围内。 – 893