【问题标题】:Primefaces datatable select row and scopePrimefaces数据表选择行和范围
【发布时间】:2013-05-31 21:47:45
【问题描述】:

我使用 PrimeFaces 3.1,我必须在数据表中选择一行。 我使用 Primefaces 展示中的示例来执行此操作,但它仅在我的支持 bean 处于范围会话中时才有效,而不是在视图中,这意味着当用户返回此页面时我必须做一些额外的工作才能将其删除,我的代码有什么问题? 我的控制器(在请求范围内):

@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 重新注入一个。

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

【问题讨论】:

  • 不需要是scopeview。
  • 发布完整的代码,因为我们看不出有什么问题。
  • 我试着只放我的代码的相关部分,但如果你认为缺少某些东西,请告诉我,我会添加它。
  • 你想对选中的行做什么?
  • 我有一个带有搜索表单的屏幕,这个搜索的结果显示在搜索表单下,然后,用户可以选择一行并查看所选行的详细信息。

标签: java jsf primefaces datatable


【解决方案1】:

我认为您可能对本教程过于关注。

请看下面一个简单的工作示例:

汽车类

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(视域)

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>

输出

如果您需要将整个项目作为 WAR/Zip 文件,请告诉我。

【讨论】:

  • 但是 @postContruct 只被调用一次,根据 viewScope (只要你在浏览器窗口/选项卡中与同一个 JSF 视图交互,这个范围内的一个 bean 就存在。它得到根据 HTTP 请求创建并在您回发到其他视图后被销毁。)。
  • 为什么我必须把所有东西都放在构造函数中?因为相同的代码可以正常工作,只需将支持 bean 放入会话而不是视图范围。
  • 好的,如果你想要这个作为会话视图,那么它就可以了。
  • 我正在使用会话,因为它在视图中不起作用。但我想明白为什么?因为会话和视图范围只是存储一些信息的一种方式,但会话更像是一个永久存储(跨不同页面)而不是视图,我只想在用户在页面上时存储我的数据
  • 我在多选时遇到了类似的问题。有人可以帮忙吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2015-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
相关资源
最近更新 更多