【问题标题】:p:dataTable Not Editingp:dataTable 未编辑
【发布时间】:2018-05-02 00:54:41
【问题描述】:

我正在尝试创建一个带有单击单元格编辑的数据表,如下所示:https://www.primefaces.org/showcase/ui/data/datatable/edit.xhtml

我遇到的问题是该表不会考虑修改。 显示 MySQL 数据库中的数据没有问题。该表已正确加载,没有错误。当我尝试修改一个单元格时,它会按预期变成一个输入。但是当我更改值并按回车键时,单元格会恢复到原来的值。如果我在该单元格上重新进入编辑模式,我的修改会再次出现。未在数据库中进行任何修改。

我对 JSF 和 PrimeFaces 不太满意,而且我肯定遗漏了一些明显的东西。

这是我的代码:

托管 Bean:

package Application;

import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;


@Named(value = "plantCtrl")
@ViewScoped

public class PlantCtrl implements Serializable {

    @EJB
    private PlantDAO plantDAO;

    public PlantCtrl() {
    }

    @PostConstruct
    public void init(){
    }

    public List<Plant> getPlants() {
        return plantDAO.allPlants();
    }

    public PlantDAO getPlantDAO() {
        return plantDAO;
    }

    public void setPlantDAO(PlantDAO plantDAO) {
        this.plantDAO = plantDAO;
    }

    public void onRowEdit(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Plant Edited");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onRowCancel(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Edit Cancelled");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onCellEdit(CellEditEvent event) {
        Object oldValue = event.getOldValue();
        Object newValue = event.getNewValue();

        if(newValue != null && !newValue.equals(oldValue)) {
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }
}

植物道:

package Application;

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class PlantDAO {

    @PersistenceContext(unitName = "CarnivorousGardenPU")
    private EntityManager em;

    public List<Plant> allPlants() {
        Query query = em.createNamedQuery("Plant.findAll");
        return query.getResultList();
    }

    public void add(Plant p) {
        em.persist(p);
        em.flush();
    }

    public void edit(Plant p) {
        em.merge(p);
        em.flush();
    }

    public void remove(Plant p) {
        em.remove(em.merge(p));
        em.flush();
    }
}

XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<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"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

    <h:head>
        <title>Dashboard</title>
    </h:head>

    <h:body>

        <ui:include src="inc/header.xhtml" />

        <h:form id="plantAdminList">

            <p:growl id="msgs" showDetail="true"/>

            <p:dataTable id="plantsTable" var="plant" value="#{plantCtrl.plants}" editable="true" editMode="cell" widgetVar="cellPlants">
               <f:facet name="header">
                   Cell Editing with Click and RightClick
               </f:facet>

                <p:ajax event="cellEdit" listener="#{plantCtrl.onCellEdit}" update=":plantAdminList:msgs, :plantAdminList:plantsTable" />

                <p:column headerText="Id">
                    <p:cellEditor>
                        <f:facet name="output"><h:outputText value="#{plant.genusPlant}" /></f:facet>
                        <f:facet name="input"><p:inputText id="modelInput" value="#{plant.genusPlant}" style="width:96%"/></f:facet>
                    </p:cellEditor>
                </p:column>

                <p:column headerText="Price">
                    <p:cellEditor>
                        <f:facet name="output"><h:outputText value="#{plant.pricePlant}" /></f:facet>
                        <f:facet name="input"><p:inputText value="#{plant.pricePlant}" style="width:96%" label="Price"/></f:facet>
                    </p:cellEditor>
                </p:column>

            </p:dataTable>

        </h:form>

        <ui:include src="/inc/footer.xhtml" />

    </h:body>

</html>

Plant.java 由 Netbeans 作为来自数据库的实体类自动生成。我不会因为不超载这篇文章而发布它,但如果需要,请不要犹豫。

【问题讨论】:

  • 嗨,需要的是minimal reproducible example。这可以帮助您缩小问题范围(有时甚至可以帮助您自己解决问题)并且可以帮助我们帮助您...
  • 而且 99.9% 的这类问题都不是 jsf 和数据库相关的。只需将其分开并查看该值是否最终出现在服务器上。如果不是,那纯粹是 jsf 相关的。如果是,则纯粹是与数据库相关的 abd 而不是 jsf

标签: jsf primefaces datatable


【解决方案1】:

像这样修改托管 bean 的几行

//....

List<Plant> plants;

@PostConstruct
public void init(){
  plants=plantDAO.allPlants();
}

public List<Plant> getPlants() {
    return plants;
}

//....

它会按您的意愿工作:当您更改值并按 Enter 时,单元格将反映您的更改。

请注意:

如果你想持久化对数据库的更改,你需要稍微修改你的p:dataTable 并在托管bean 中创建额外的逻辑来检测修改并将它们传递给已经存在的plantDao.edit 方法。最少的编码是:

  1. 这样修改数据表

    p:dataTable id="plantsTable" var="plant" value="#{plantCtrl.plants}" editable="true" widgetVar="cellPlants">
    
         <p:ajax event="rowEdit" listener="#{plantCtrl.onRowEdit}" 
                 update=":plantAdminList:msgs, :plantAdminList:plantsTable" />
     ....
        <p:column style="width:32px">
            <p:rowEditor />
        </p:column>
    </p:dataTable>
    
  2. 在托管 bean 中修改 onEditMethod

    public void onRowEdit(RowEditEvent event) {
        Plant editedPlant = (Plant)event.getObject();
        plantDAO.edit(plant);
    
        FacesMessage msg = new FacesMessage("Plant Edited");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    

【讨论】:

  • 嘿,谢谢你的回答,它成功了!你知道我怎样才能持久化数据吗?问题是 event.getNewValue() 将根据单元格返回字符串、浮点数等。它不会返回对象本身,这使得之后使用我的编辑方法变得复杂。有没有办法从事件中获取编辑的对象?
  • @Cephou,我用其他解释更新了我的答案。另请查看有关此subject 的文档
猜你喜欢
  • 2017-01-16
  • 2014-09-30
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 2016-04-26
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多