2015-01-07 2 views
1

Простое приложение, которое использует Primefaces datatables with radio button selection, ведет себя неправильно. Когда я выбираю элемент с переключателем, аргумент event равен null в методе delete(), поэтому выбранная строка не может быть удалена из datatable.Как удалить элемент из datatable

View.xhtml // Вот где я получаю проблемы

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://xmlns.jcp.org/jsf/html" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:f="http://xmlns.jcp.org/jsf/core"> 
<h:head> 
    <title>Event List</title> 
</h:head> 
<h:body> 
    <h:form> 
     <p:dataTable id="eventlist" var="event" value="#{eventBean.eventlist}" selection="#{eventBean.selectedEvent}" rowKey="#{event.id}" scrollable="true" scrollHeight="200" style="width:500px;"> 
      <f:facet name="header"> 
       Event List 
      </f:facet> 
      <p:column selectionMode="single" style="width:16px;text-align:center"/> 
      <p:column headerText="ID"> 
       <h:outputText value="#{event.id}"> 
       </h:outputText> 
      </p:column> 
      <p:column headerText="Date"> 
       <h:outputText value="#{event.date}"> 
        <f:convertDateTime pattern="yyyy-MM-dd" /> 
       </h:outputText> 
      </p:column> 
      <f:facet name="footer"> 

       <p:commandButton process="eventlist" action="#{eventBean.delete(eventBean.event)}" value="#{eventBean.event}" ajax="true" > 

       </p:commandButton> 
      </f:facet> 
     </p:dataTable> 
    </h:form> 
</h:body> 

EventBean.java // Это мой управляемый компонент

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.annotation.ManagedBean; 
import javax.ejb.EJB; 
import javax.inject.Named; 
import javax.enterprise.context.RequestScoped; 

@ManagedBean 
@Named(value = "eventBean") 
@RequestScoped 
public class EventBean { 

@EJB 
private EventManager em; 

private Event event; 

private Event selectedEvent = new Event(); 

private Date currentDate; 

private List<Event> eventlist = new ArrayList<Event>(); 


public Date getCurrentDate() { 
    if (currentDate == null) { 
     currentDate = new Date(); 
    } 
    return currentDate; 
} 

public EventBean() { 
} 

public Event getEvent() { 
    if (event == null) { 
     event = new Event(); 
    } 
    return event; 
} 

public void setEvent(Event event) { 
    this.event = event; 
} 

public List<Event> getEventlist() { 
    return eventlist; 
} 

public void setEventlist(List<Event> eventlist) { 
    this.eventlist = eventlist; 
} 

public Event getSelectedEvent() { 

    return selectedEvent; 
} 

public void setSelectedEvent(Event selectedEvent) { 
    this.selectedEvent = selectedEvent; 
} 

public String create() { 
    em.save(event); 
    eventlist = em.findEvents(); 
    return "view"; 
} 

public String delete(Event event){ //the event object is null 
    em.deleteEvent(event); 
    return "index"; 
} 
} 

Краткая информация что я хотел бы достичь: правильно выбрать строку из datatable, а затем удалить ее как из datatable, так и из базы данных.

ответ

1

Выбранные параметры заданы как #{eventBean.selectedEvent}, но вы проходите #{eventBean.event} вперед и назад к методу удаления. Эта проблема в два раза. Во-первых, это неправильное свойство. Во-вторых, вам не нужно передавать его вперед и назад. Это уже в фасоли.

Таким образом, это должно сделать:

<p:commandButton ... action="#{eventBean.delete}" /> 

с

public String delete() { 
    em.deleteEvent(selectedEvent); 
    return "index"; 
} 

Еще одна странная вещь, что вы нигде не инициализирует eventlist во время инициализации компонента. Это означает, что когда вы отправляете форму, во время этого нового запроса, в котором компонент, обработанный запросом, был вновь создан и инициализирован, eventlist будет null, и, таким образом, не будет ничего доступного для выбора и установки в модели.

Вы должны иметь следующий метод в EventBean:

@PostConstruct 
public void init() { 
    eventlist = em.findEvents(); 
} 

Таким образом, вы должны теперь также быть в состоянии увидеть список уже тогда, когда только непосредственно открыв view.xhtml в браузере без первого представления произвольной формы в другую страницу , Другими словами, теперь это наконец idempotent.


Unrelated к конкретной задаче, вы смешиваете JSF и управления CDI боб аннотаций. Избавьтесь от аннотации @ManagedBean. Вы также выполняете ленивую загрузку в методах getter. Избавьтесь от них всех и выполните работу в @PostConstruct и оставьте методы автогенерированного геттера (и сеттера) нетронутыми. Таким образом, вы также можете легко предоставить более короткие фрагменты кода в вопросах, где вы опускаете все геттеры/сеттеры, потому что они достаточно очевидны.

+0

Я попытался изменить код, как вы предложили, но я получил этот журнал: Alert: Исключение системы произошло во время вызова на EJB EventManager, метод: общественного недействительный boundary.EventManager.deleteEvent (entity.Event) оповещение : javax.ejb.EJBException [...] на com.sun.proxy. $ Proxy244.deleteEvent (Unknown Source) на границе .__ EJB31_Generated__EventManager__Intf ____ Bean __. DeleteEvent (Unknown Source) на control.EventController.delete (EventController.java:86) [...] Вызвано: java.lang.IllegalArgumentException: Object: null не является известным типом сущности. [...] – jiasheng

+0

В вашем коде не видно, как вы готовите и сохраняете «список событий». Это в основном пустой список, который, как я предполагал, является результатом упрощения кода. Попробуйте разместить http://stackoverflow.com/help/mcve – BalusC

+0

В исходном тексте вопроса были созданы все созданные файлы проекта, кроме сущности Event.java. Однако список событий списка List предназначен только для отображения данных в заданной для данных целях, а не для деления события, которому я присвоил переменную Event selectedEvent. Я думаю, что теперь моя главная проблема заключается в том, что selection = "# {eventBean.selectedEvent}" не получает выбранное событие. – jiasheng

Смежные вопросы