使用Primefaces datatables with radio button selection的简单应用程序无法正常运行。
当我选择带单选按钮的元素时,event
参数在null
方法中为delete()
,因此无法从数据表中删除所选行。
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 // 这是我的托管bean
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";
}
}
简单地说,我想要实现的是:从数据表中正确选择行,然后从数据表和数据库中删除它。
答案 0 :(得分:1)
选择设置为#{eventBean.selectedEvent}
,但您将#{eventBean.event}
向前传递回delete方法。这个问题是双重的。首先,它是错误的财产。其次,你不需要经常传递它。它已经在豆子里了。
所以,这应该做:
<p:commandButton ... action="#{eventBean.delete}" />
与
public String delete() {
em.deleteEvent(selectedEvent);
return "index";
}
另一个奇怪的事情是,在bean的初始化过程中,你无法初始化eventlist
。这意味着当您提交表单时,在新请求中,其中新构造并初始化了请求范围bean,eventlist
将为null
,因此没有任何内容可供选择和设置模型。
您应该在EventBean
中使用以下方法:
@PostConstruct
public void init() {
eventlist = em.findEvents();
}
这样,您现在也可以在浏览器中直接打开view.xhtml
时看到列表,而无需先在另一个页面中提交任意表单。换句话说,它现在终于idempotent。
无关,您需要混合使用JSF和CDI bean管理注释。完全摆脱@ManagedBean
注释。您还在getter方法中执行延迟加载。摆脱它们并在@PostConstruct
中完成工作并保持自动生成的getter(和setter)方法不变。通过这种方式,您可以轻松地在问题中提供更多短代码片段,省略所有getter / setter,因为它们非常明显。