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

6

Я пытаюсь изучить 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   ответа
25

#{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.

Либо используйте составной ключ, либо создайтеSelectableDataModel.
Что мы делаем, если есть 2 первичных ключа, что мы делаем в таком сценарии? user1226447
rowKey в основном сообщает PrimeFaces, какой уникальный идентификатор строки.selection в основном сообщает PrimeFaces, где он должен получить / установить ссылки на выбранные строки. ТочкаSelectableDataModel должен иметь возможность идентифицировать уникальные строки на основе других критериев, помимо того, что уже доступно самим объектом строки (для которого вам потребуетсяrowKey).
Спасибо за комментарий, BalusC, у меня есть пара вопросов, какая польза от rowKey? Это уникальное значение для отображаемого столбца таблицы? Что если у меня есть, скажем, 2 первичных ключа в одной таблице. Другой вопрос: что вы имеете в виду, если я использую rowKey, мне не нужно реализовывать CarDataModel, не могли бы вы немного объяснить ... а также можете пролить свет на то, что атрибут выбора делает в & lt; P: table & gt; user1226447
Обратите внимание, что вы все равно можете получить ту же ошибку, даже если вы определили атрибут rowKeyif упомянутый атрибут возвращает нуль (например, он не инициализирован).
0

owkey, например: rowKey = & quot; # {course.getCompositeKey ()

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

1

который заполняет значение & quot; value = .. & quot; из данных. Мой вернул эту ошибку, потому что rowKey был нулевым.

0

просто укажите в свойствах datatable & lt; rowkey & quot; вот так: rowkey = & quot; {mbean.atribute1} & quot;
  - Атрибут1 должен отображаться в столбце таблицы данных.

Must
Параметр rowkey являетсяnot требуется отображать в виде столбца в таблице данных.

Похожие вопросы