2016-11-24 77 views
0

我正面临着JSF和Datatables的一些麻烦。在我的bean中,我有一个依靠Datatable显示在视图中的对象列表。该对象非常简单,每个都由一个整数(id)和一个字符串( 评论)组成。JSF Datatable:通过单个命令按钮提交多行

最终目标是将对象的完整列表打印到用户,同时将编辑一行或多行(通过h:inputtext字段),然后通过按钮提交其更改。这就是问题所在。我已经使用“成功”数据表,通过依靠每行上的编辑/保存按钮来编辑每行一行,但在这种情况下不适用,因为最终用户将面对多于500行的总计。

这里是我使用(简化的和萃取)

豆的代码:

@ManagedBean 
@RequestedScope 
public class VlanBean { 

private DataModel<VlanWrapper> model; 

private List<VlanWrapper> vlans = new ArrayList<VlanWrapper>(); 

public VlanBean() { 
    vlans.add(new VlanWrapper(1, "")); 
    vlans.add(new VlanWrapper(2, "Prova2-2")); 
    vlans.add(new VlanWrapper(3, "")); 
    vlans.add(new VlanWrapper(4, "")); 
    vlans.add(new VlanWrapper(5, "")); 
    vlans.add(new VlanWrapper(6, "Prova3")); 
    vlans.add(new VlanWrapper(7, "")); 
    vlans.add(new VlanWrapper(8, "")); 
} 

public void commitChanges() 
{ 
    System.out.println("Before Model "); 

    for (VlanWrapper vw : model) 
    { 
     System.out.println("ModelOF " + vw.getId() + " - " + vw.getProject() + " - changed: " + vw.changed + ";"); 
    } 
} 

public DataModel<VlanWrapper> getModel() { 
    if (model == null) 
     model = new ListDataModel<VlanWrapper>(vlans); 
    return model; 
} 

public void setModel(DataModel<VlanWrapper> model) { 
    this.model = model; 
} 

public class VlanWrapper 
{ 
    private boolean changed; 
    private int id; 
    private String project; 

    public VlanWrapper(int id, String prj) 
    { 
     this.id = id; 
     this.project = prj; 
     changed = false; 
    } 

    public String getProject() { 
     return project; 
    } 

    public void setProject(String project) { 
     System.out.println("Setting PRJ.."); 
     changed = true; 
     this.project = project; 
    } 

    public int getId() { 
     return id; 
    } 

    public boolean isChanged() { 
     return changed; 
    } 
} 
} 

检视:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:f="http://java.sun.com/jsf/core" 
xmlns:h="http://java.sun.com/jsf/html" 
xmlns:ui="http://java.sun.com/jsf/facelets"> 
<h:head> 
</h:head> 
<h:body> 
<f:view> 
    <h:panelGroup> 
    <h:form> 
     <h:commandButton value="Commit changes to DB" action="#{VlanBean.commitChanges}"> 
     </h:commandButton> 
    </h:form> 


    <h:dataTable value="#{VlanBean.model}" var="vlans"> 
     <h:column><f:facet name="header">ID</f:facet>#{vlans.id}</h:column> 
     <h:column><f:facet name="header">Project</f:facet> 
      <h:inputText value="#{vlans.project}" immediate="true"/> 
     </h:column> 
    </h:dataTable> 
    </h:panelGroup> 

</f:view> 
</h:body> 
</html> 

的问题是,所有的变化我的视图做没有反映在豆,我还没有找到任何有用的提示/张贴周围(一些建议阿贾克斯强迫更新,其他的JavaScript,但我没有让他们中的任何工作,没有人是真的关闭我希望使用它)。

我也尝试去为ui:重复,但我有同样的行为。任何想法/建议?我没有义务使用Datatable,所以我打开其他解决方案/方法!

谢谢advace, 阿尔贝托

回答

0

从你的代码,你应该得到一个警告说你<h:inputText应该有一个<f:form作为父母;没有任何形式的周围,你有形式只是围绕<h:commandButton

使用任何类型的Iteration UIComponent你可以有你想要的行为,但通常使用<h:datatable。尽管您必须先选择要编辑的行,但您肯定可以自己找到解决方案,但您可以这样做的方法如下:

我向您的实体添加了另一个属性VlanWrapper

private boolean changed; 
private boolean edit; 
private int id; 
private String project; 

// setter方法&干将....

你的facelet可能是这样的:

<h:form> 
    <h:dataTable value="#{meod.vlans}" var="v" > 

     <h:column> 
      <f:facet name="header">Id</f:facet> 
      <h:outputLabel value="#{v.id}" />      
     </h:column> 

     <h:column> 
      <f:facet name="header">Project</f:facet> 
      <h:outputLabel rendered="#{not v.edit}" value="#{v.project}" /> 
      <h:inputText rendered="#{v.edit}" value="#{v.project}" > 
       <f:ajax event="blur" execute="@this" listener="#{meod.addToEditedList(e)}" render="@all"> 
        <f:param name="vlanedit" value="#{v.id}" /> 
        <f:param name="vlanproject" value="#{v.project}" /> 
       </f:ajax> 
      </h:inputText> 
     </h:column> 

     <h:column> 
      <f:facet name="header">Edit</f:facet> 
      <h:commandButton value="Edit" action="#{meod.edit(v)}"> 
       <f:ajax render="@form" /> 
      </h:commandButton> 
     </h:column> 
    </h:dataTable>    
    <h:commandButton value="Finalize Edit" action="#{meod.editSubmit()}" /> 
</h:form> 

之所以我说你必须选择你想要编辑的行是因为当你按下edit按钮时,整个表单将被更新,所以你只需要更新你想要更新的东西,这应该做到这一点。

的backingbean:

@ManagedBean 
@ViewScoped 
public class Meod { 

    private List<VlanWrapper> vlans; 

    public Meod() { 

     vlans = new ArrayList<>(); 

     for (int i = 0; i < 11; i++) { 

      vlans.add(new VlanWrapper(i, "Project " + i)); 
     } 
    } 

    public void addToEditedList(AjaxBehaviorEvent e) { 

     Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); 

     int id = Integer.valueOf(params.get("vlanedit")); 
     String newProject = params.get("vlanproject"); 

     updateVlanInView(id, newProject); 
    } 

    private void updateVlanInView(int id, String proj) { 

     vlans.stream().filter(v -> v.getId() == id).forEach(v -> v.setProject(proj)); 
    } 

    public void edit(VlanWrapper vlan2Edit) { 
     vlan2Edit.setEdit(true); 
    } 

    public void editSubmit() { 
     vlans.forEach((v) -> v.setEdit(false)); 
    } 

    public List<VlanWrapper> getVlans() { 
     return vlans; 
    } 

    public void setVlans(List<VlanWrapper> vlans) { 
     this.vlans = vlans; 
    } 
} 

有些情况下,你可以达到这个多种方式...到但可能更好的方式来概括:

  • 创建一个DataTable来遍历你的对象
  • 确保您<h:commandXXXEditableValueHolder s为一张表。
  • “new”属性edit用于确定是否渲染输入而不是输出文本组件
  • 使用DBService在更改后更新值。

希望这会有所帮助。

+0

非常感谢您的回答,它为我澄清了几点!实际上我需要实现的流程我不需要编辑属性,但它是一个非常好的命题和示例!尤其是ajax部分! – kappaalby

0

将您的</h:form>标签移动到数据表后面。这将包含您的更改,现在将正确调用setProject方法。

<h:panelGroup> 
    <h:form> 
     <h:commandButton value="Commit changes to DB" action="#{VlanBean.commitChanges}"> 
     </h:commandButton> 

     <h:dataTable value="#{VlanBean.model}" var="vlans"> 
      <h:column><f:facet name="header">ID</f:facet>#{vlans.id}</h:column> 
      <h:column><f:facet name="header">Project</f:facet> 
      <h:inputText value="#{vlans.project}" immediate="true"/> 
      </h:column> 
     </h:dataTable> 
    </h:form> 
</h:panelGroup> 
+0

谢谢!这是我失踪的一块! – kappaalby