2016-11-24 78 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