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 должен отображаться в столбце таблицы данных.