【问题标题】:How to remove element from datatable如何从数据表中删除元素
【发布时间】:2015-03-05 20:27:29
【问题描述】:

使用 Primefaces datatables with radio button selection 的简单应用程序无法正常运行。 当我选择一个带有单选按钮的元素时,event 参数在delete() 方法中为null,因此无法从数据表中删除所选行。

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

简而言之,我想要实现的是:从数据表中正确选择行,然后从数据表和数据库中删除它。

【问题讨论】:

    标签: jsf jsf-2 primefaces datatable


    【解决方案1】:

    选择设置为#{eventBean.selectedEvent},但您将#{eventBean.event} 来回传递并返回到删除方法。这个问题是双重的。首先,这是错误的属性。其次,您不需要来回传递它。它已经在 bean 中了。

    所以,应该这样做:

    <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 的问题中轻松提供更短的代码 sn-ps,因为它们足够明显。

    【讨论】:

    • 我尝试按照您的建议修改代码,但收到以下日志:警报:在 EJB EventManager 上调用期间发生系统异常,方法:public void boundary.EventManager.deleteEvent(entity.Event)警报:com.sun.proxy.$Proxy244.deleteEvent(Unknown Source) atboundary.__EJB31_Generated__EventManager__Intf____Bean__.deleteEvent(Unknown Source) at control.EventController.delete(EventController.java:86) 处的 javax.ejb.EJBException [...] [...] 引起:java.lang.IllegalArgumentException:对象:null 不是已知的实体类型。 [...]
    • 在您的代码中看不到您如何准备和保存eventlist。它基本上是一个空列表,我认为这是代码过度简化的结果。尝试发布stackoverflow.com/help/mcve
    • 问题原文中除了实体Event.java之外,都是项目创建的所有文件。但是,变量 List eventlist 仅用于显示数据表中的数据,而不是用于选择事件,我为其分配了变量 Event selectedEvent。我认为我现在的主要问题是 selection="#{eventBean.selectedEvent}" 没有得到选定的事件。
    • 你应该在 bean 的 @PostConstruct 中做 eventlist = em.findEvents();,最好让 bean @ViewScoped
    • 我认为@PostConstruct 不是我的问题,因为我实际上可以看到存储数据的整个列表。但无论如何我尝试了你的方法,但如果我使用 ViewScoped,我会在创建和显示事件列表时得到 EJBException(这是曾经工作的部分)。
    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 2010-10-13
    • 2019-07-29
    • 2014-11-13
    • 2013-10-17
    • 2021-03-10
    • 1970-01-01
    相关资源
    最近更新 更多