FacesException: DataModel должен реализовывать org.primefaces.model.SelectableDataModel, когда выбор включен

Я пытаюсь изучить PF, поэтому я начал с отображения данных вначале и перехода к следующей странице с параметрами передачи rowClick, но застрял со следующей ошибкой. Я нашел похожую проблему для этого вопроса, но пока не повезло. Я надеюсь, что кто-нибудь поможет мне.

Я получаю следующую ошибку:

DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.

Caused by:
javax.faces.FacesException - DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.

моя страница:

 <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">

<h:head>
<title>Primefaces 3.1</title>

</h:head>
<h:body>
    <h:form id="form">          
            <p:dataTable value="#{tableBean.cars}" var="var" rowkey="#{var.model}" 
            selection="#{tableBean.car}" selectionMode="single">
            <p:column>  <f:facet name="header">
                                <h:outputText styleClass="outputText" value="Model"></h:outputText>
                            </f:facet>
                            <h:outputText styleClass="outputText"
                                value="#{var.model}"></h:outputText>
                        </p:column>
                        <p:column>
                            <f:facet name="header">
                                <h:outputText styleClass="outputText" value="Color"></h:outputText>
                            </f:facet>
                            <h:outputText styleClass="outputText"
                                value="#{var.randomColor}"></h:outputText>
                        </p:column></p:dataTable>                               
        </h:form>
</h:body>
</html>

Мои бобовые классы:

@ManagedBean
@ViewScoped
public class TableBean extends ListDataModel<Car> implements SelectableDataModel<Car>{

    private List<Car> cars;
    private Car car;

    public List<Car> getCars() {

        cars = new ArrayList<Car>();
        Car car1 = new Car();
        car1.setModel("BMW");
        car1.setRandomColor("Black");
        cars.add(car1);
        Car car2 = new Car();       
        car2.setModel("Audi");
        car2.setRandomColor("White");
        cars.add(car2);

        return cars;
    }

    public String onRowSelect(){
        System.out.println("Row Click!!!");
        return "otherpage";//Does this nav works???if not how???
    }

    public Car getCar() {
        return car;
    }

    @Override
    public Car getRowData(String pArg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object getRowKey(Car pArg0) {
        // TODO Auto-generated method stub
        return null;
    }   
    }

OtherBean:

public class Car{

    private String model;   
    private String randomColor; 

    public String getRandomColor() {
        return randomColor;
    }
    public void setRandomColor(String pRandomColor) {
        randomColor = pRandomColor;
    }

    public String getModel() {
        return model;
    }
    public void setModel(String pModel) {
        model = pModel;
    }

}

4 ответа

Решение

#{tableBean.cars} должен реализовать SelectableDataModel если вы не укажете rowKey атрибут на <p:dataTable>,

Однако вы реализовали это на #{tableBean} вместо. Это неправильно. Вы можете найти правильные примеры в витрине PrimeFaces. В основном, ваш TableBean класс должен выглядеть следующим образом в соответствии с примером кода витрины:

@ManagedBean
@ViewScoped
public class TableBean implements Serializable {

    private List<Car> cars;
    private Car car;
    private CarDataModel carsModel;

    public TableBean() {
        cars = new ArrayList<Car>();
        // Populate cars here and thus NOT in the getter method!
        carsModel = new CarDataModel(cars);
    }

    // ...
}

Где CarDataModel выглядеть следующим образом (опять же, только что скопированный из примера кода PrimeFaces):

public class CarDataModel extends ListDataModel<Car> implements SelectableDataModel<Car> {  

    public CarDataModel() {
    }

    public CarDataModel(List<Car> data) {
        super(data);
    }

    @Override
    public Car getRowData(String rowKey) {
        List<Car> cars = (List<Car>) getWrappedData();

        for(Car car : cars) {
            if(car.getModel().equals(rowKey))
                return car;
        }

        return null;
    }

    @Override
    public Object getRowKey(Car car) {
        return car.getModel();
    }

}

Наконец использовать #{tableBean.carsModel} вместо #{tableBean.cars} как значение <p:dataTable>, Точно так же, как в примере с витриной.

<p:dataTable value="#{tableBean.carsModel}" var="car" ... />

Другой, более простой способ - просто указать rowKey атрибут на <p:dataTable>,

<p:dataTable value="#{tableBean.cars}" var="car" rowKey="#{car.model}" ... />

Таким образом, вам не нужно все SelectableDataModel, Вам нужно только убедиться, что это никогда null и всегда уникален во всех рядах. См. Также DataModel должен реализовывать org.primefaces.model.SelectableDataModel, когда выбор разрешен, но я уже определил rowKey.

Обязательно установите параметр rowKey в методе bean-компонента, который заполняет значение "= =" объекта данных. Мой вернул эту ошибку, потому что rowKey был нулевым.

Это работало для моего проекта с использованием составного ключа для rowkey, например: rowKey="#{course.getCompositeKey()

Поскольку у меня не было переменной композитного ключа, я просто создал его в своем классе курса (в вашем случае, в классе автомобилей). 2 первичных ключа являются строками, поэтому я просто сказал this.compositeKey=this.courseNumber+this.product- вы просто используете любые 2 первичных ключа в вашем классе Car вместо courseNumber и product.

Вам не нужно реализовывать datamodal в вашем управляемом бобе, просто укажите в свойствах datatable "rowkey", например: rowkey = "{mbean.atribute1}"
- Атрибут1 должен отображаться в столбце таблицы данных.

Должен

Другие вопросы по тегам