2012-05-10 11 views
5

Sto cercando di imparare PF quindi ho iniziato a visualizzare datatable prima e navigando alla pagina successiva su rowClick passando parametri, ma mi sono bloccato con il seguente errore. Ho trovato un problema simile a quella domanda, ma ancora senza fortuna. Spero che qualcuno mi aiuti.FacesException: DataModel deve implementare org.primefaces.model.SelectableDataModel quando la selezione è abilitata

sto ottenendo seguente errore:

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. 

mia pagina:

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

mie classi di fagioli:

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

} 

risposta

23

Il #{tableBean.cars} deve implementare SelectableDataModel se non si specifica l'attributo rowKey su <p:dataTable>.

Avete comunque implementato sul posto il #{tableBean}. Questo non è giusto. È possibile trovare esempi corretti nello PrimeFaces showcase. In sostanza, la classe TableBean deve assomigliare a questo secondo il codice vetrina esempio:

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

    // ... 
} 

dove lo sguardo CarDataModel come questo (ancora una volta, solo copiato da primefaces vetrina esempio di codice):

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

} 

Infine usare #{tableBean.carsModel} anziché #{tableBean.cars} come valore di <p:dataTable>. Esattamente come nell'esempio della vetrina.

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

Un altro, più facile, modo è quello di indicare solo l'attributo rowKey sul <p:dataTable>.

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

In questo modo non è necessario l'intero SelectableDataModel. Devi solo assicurarti che non sia mai null e sempre univoco tra le righe. Vedi anche DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled, but I have already defined rowKey.

+0

Grazie per il commento, BalusC, ho un paio di domande, qual è l'uso di rowKey? È per il valore univoco per la colonna della tabella visualizzata? Cosa succede se ho diciamo 2 chiave primaria nella stessa tabella. Un'altra domanda è: cosa intendi con se uso rowKey non devo implementare CarDataModel, puoi spiegare un po '... e puoi anche fare luce su quale attributo di selezione fa in . – user1226447

+0

Il 'rowKey' dice fondamentalmente a PrimeFaces quale sia l'identificatore univoco della riga. La 'selection' dice fondamentalmente a PrimeFaces dove deve ottenere/impostare i riferimenti delle righe selezionate. Il punto di "SelectableDataModel" deve essere in grado di identificare le righe univoche basate su altri criteri rispetto a ciò che è già disponibile dall'oggetto riga stesso (per il quale è necessario 'rowKey'). – BalusC

+0

Cosa facciamo se ci sono 2 chiavi primarie, cosa facciamo in tale scenario? – user1226447

0

ha funzionato per il mio progetto utilizzando una chiave composito per rowkey esempio: rowKey = "# {course.getCompositeKey()

Dal momento che non ho avuto una variabile compositeKey ho semplicemente creato uno nella mia classe golf (in il tuo caso la classe dell'auto) .Le 2 chiavi primarie sono stringhe quindi ho appena detto this.compositeKey = this.courseNumber + this.product - tu usi semplicemente le 2 chiavi primarie nella tua classe Car invece del numero e del prodotto

0

Non è necessario implementare il datamodal nel beanbase, basta specificare nella proprietà del datatable la "riga di comando" come questa: rowkey = "{mbean.atribute1}"
- atribute1 deve essere visualizzato nella colonna della tabella di dati.

Must

+0

Il parametro chiave di riga * non * deve essere visualizzato come colonna nella tabella dati. –

1

Assicurarsi di impostare il parametro rowKey nel metodo di fagioli che popola la "value = .." della datatable. Il mio ha restituito questo errore perché rowKey era nullo.

Problemi correlati