2012-05-10 24 views
5

Estoy tratando de aprender PF, así que comencé mostrando la tabla de datos primero y navegando a la página siguiente en los parámetros de paso rowClick, pero me quedé con el siguiente error. Encontré un problema similar para esa pregunta, pero aún no tuve suerte. Espero que alguien me ayude.FacesException: DataModel debe implementar org.primefaces.model.SelectableDataModel cuando la selección está habilitada

estoy consiguiendo error siguiente:

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. 

mi página:

<?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> 

mis clases de frijol:

@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; 
    } 

} 

Respuesta

23

El #{tableBean.cars} debe implementar SelectableDataModel si no especifica el atributo rowKey en el <p:dataTable>.

Sin embargo, lo ha implementado en el #{tableBean} en su lugar. Esto no está bien. Puede encontrar ejemplos correctos en el PrimeFaces showcase. Básicamente, su clase TableBean debe tener este aspecto de acuerdo con el ejemplo de código escaparate:

@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); 
    } 

    // ... 
} 

Cuando la mirada CarDataModel como esto (de nuevo, simplemente copiada de PrimeFaces escaparate ejemplo de código):

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(); 
    } 

} 

usan último #{tableBean.carsModel} en lugar de #{tableBean.cars} como valor de <p:dataTable>. Exactamente como en el ejemplo del escaparate.

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

Otro, más fácil, manera de hacerlo es simplemente especificar el atributo rowKey en el <p:dataTable>.

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

De esta manera no es necesario todo el SelectableDataModel. Solo necesita asegurarse de que nunca sea null y siempre único en todas las filas. Vea también DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled, but I have already defined rowKey.

+0

Gracias por el comentario, BalusC, tengo un par de preguntas, ¿para qué sirve rowKey? ¿Es por el valor único para la columna de la tabla que se muestra? ¿Qué sucede si tengo que decir 2 claves principales en la misma tabla? Otra pregunta es, ¿a qué te refieres con si uso rowKey? No tengo que implementar CarDataModel, ¿puedes explicarlo un poco? Y también puedes aclarar qué atributo de selección hace en . – user1226447

+0

El 'rowKey' básicamente le dice a PrimeFaces cuál es el identificador único de la fila. La 'selección' básicamente le dice a PrimeFaces dónde tiene que obtener/establecer las referencias de las filas seleccionadas. El objetivo de 'SelectableDataModel' es poder identificar filas únicas basadas en otros criterios distintos de los que ya están disponibles para el objeto de la fila (para lo cual necesitaría' rowKey'). – BalusC

+0

¿Qué hacemos si hay 2 claves principales, qué hacemos en dicho escenario? – user1226447

0

funcionó para mi proyecto utilizando una clave compuesta por rowKey por ejemplo: rowKey = "# {course.getCompositeKey()

Como yo no tengo una variable compositeKey simplemente creé uno en mi clase de golf (en su caso, la clase del coche). Las 2 claves principales son cadenas, así que acabo de decir this.compositeKey = this.courseNumber + this.product - solo usa las 2 claves principales que están en su clase Car en lugar de courseNumber y producto.

0

No tiene que implementar el datamodal en su beans administrado, solo especifique en la propiedad de la tabla de datos la "clave de fila" de esta manera: rowkey = "{mbean.atribute1}"
- atribute1 debe aparecer en la columna de la tabla de datos.

Debe

+0

El parámetro de clave de fila * * no es necesario para mostrarse como una columna en la tabla de datos. –

1

Asegúrese de establecer el parámetro rowKey en el método de frijol que puebla el "valor = .." de la tabla de datos. El mío devolvió este error porque rowKey era nulo.

Cuestiones relacionadas