2009-10-19 46 views
2

我正在嘗試創建一個JSF頁面,用戶在兩個selectOneMenu組件中選擇值。這些選擇中的值將被傳遞給SQL查詢以更新頁面上顯示的表。基於selectOneMenu值更新JSF數據表

我已經將每個選擇項綁定到支持bean中的適當變量,但在更改selectOneMenu中選定的值之後,支持bean中的綁定屬性不會更改,並且執行查詢但不會不會返回任何結果。 (順便說一句,當頁面初始顯示時,getters也會被調用兩次)。

我不能在此實現中使用任何其他第三方組件(例如RichFaces等)。

對此深表感謝!

下面是代碼:

notes.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
pageEncoding="ISO-8859-1"%> 
    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> 
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
     <title></title> 
</head> 
<body> 

<f:view> 

<h:form id="notelistform"> 
    <f:subview id="loginbar"> 
     <jsp:include page="/jsp/loginbar.jsp" /> 
    </f:subview> 

    <h:outputText value="Worktype:" /> 
    <h:selectOneMenu value="#{pc_noteListBacker.worktype}" 
     title="worktype" id="worktypeList" onchange="submit()"> 
     <f:selectItems value="#{pc_noteListBacker.selectWorktypes}" /> 
     <f:valueChangeListener 
      type="<package>.web.backer.note.NoteListBacker" /> 

    </h:selectOneMenu> 

    <h:outputText value="Product:" /> 
    <h:selectOneMenu value="#{pc_noteListBacker.product}" title="product" 
     id="productList" onchange="submit()"> 
     <f:selectItems value="#{pc_noteListBacker.selectProducts}" /> 
     <f:valueChangeListener 
      type="<package>.web.backer.note.NoteListBacker" /> 
    </h:selectOneMenu> 


    <h:dataTable id="notelisttable" value="#{pc_noteListBacker.noteList}" 
     var="item" bgcolor="#F1F1F1" border="10" cellpadding="5" 
     cellspacing="3" first="0" width="80%" dir="LTR" frame="hsides" 
     rules="all" summary="Status and notes note table display." 
     binding="#{pc_noteListBacker.noteListTable}"> 


     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Note ID" /> 
      </f:facet> 
      <h:outputText value="#{item.noteId}"></h:outputText> 
     </h:column> 


     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Note Category" /> 
      </f:facet> 
      <h:outputText value="#{item.noteCategory}"></h:outputText> 
      <f:facet name="footer"> 
       <h:commandButton value="Add" action="#{pc_noteListBacker.insert}"> 
       </h:commandButton> 
      </f:facet> 
     </h:column> 

     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Note Subcategory" /> 
      </f:facet> 
      <h:outputText value="#{item.noteSubCategory}"></h:outputText> 
     </h:column> 


     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Note" /> 
      </f:facet> 
      <h:outputText value="#{item.note}"></h:outputText> 
     </h:column> 



     <h:column> 
      <h:commandButton value="Edit" action="#{pc_noteListBacker.edit}"> 
      </h:commandButton> 
     </h:column> 
     <h:column> 
      <h:commandButton value="Delete" action="#{pc_noteListBacker.delete}"></h:commandButton> 
     </h:column> 
    </h:dataTable> 

</h:form> 

NoteListBacker.java

package <package>.web.backer.note; 

import java.util.List; 
import java.util.ArrayList; 

import javax.faces.component.UIComponent; 
import javax.faces.component.UIComponentBase; 
import javax.faces.component.UIData; 
import javax.faces.context.FacesContext; 
import javax.faces.event.AbortProcessingException; 
import javax.faces.event.ValueChangeEvent; 
import javax.faces.event.ValueChangeListener; 
import javax.faces.model.ListDataModel; 
import javax.faces.model.SelectItem; 
import javax.swing.JOptionPane; 


public class NoteListBacker implements ValueChangeListener { 

private UIData noteListTable; 

private Note note; 

private NoteCategory noteCategory; 

private NoteSubCategory noteSubCategory; 

private NoteDao nDao; 

private SybaseSqlDao sybaseDao; 

private List<Note> noteList; 

private List<SelectItem> selectWorktypes; 

private List<SelectItem> selectProducts; 

private String worktype; 

private List<String> worktypeList; 

private String product; 

private List<Product> productList; 

private int noteId; 

public NoteListBacker() { 

    nDao = new NoteDao(); 
    sybaseDao = new SybaseSqlDao(); 
    selectWorktypes = new ArrayList<SelectItem>(); 
    selectProducts = new ArrayList<SelectItem>(); 
    noteList = new ArrayList<Note>(); 
    note = new Note(); 
    worktypeList = new ArrayList<String>(); 
    productList = new ArrayList<Product>(); 
} 

public String insert() { 
    return "success"; 
} 

public String save() { 
    return "notes"; 
} 

public String edit() { 
    return "success"; 
} 

public String update() { 
    return "notes"; 
} 

public String delete() { 
    Note delNote = (Note) noteListTable.getRowData(); 
    nDao.deleteNote(delNote); 
    return "notes"; 
} 

public String cancel() { 
    return "notes"; 
} 

public Note getNote() { 
    return note; 
} 

public void setNote(Note note) { 
    this.note = note; 
} 

public NoteDao getNDao() { 
    return nDao; 
} 

public UIData getNoteListTable() { 
    return noteListTable; 
} 

public void setNoteListTable(UIData noteListTable) { 
    this.noteListTable = noteListTable; 
} 

public List<Note> getNoteList() { 


    noteList = nDao.selectNotes(worktype, product); // 
    return noteList; 
} 

public void setNoteList(List<Note> noteList) { 
    this.noteList = noteList; 
} 

public void setNDao(NoteDao dao) { 
    nDao = dao; 
} 

public String getProduct() { 
    return product; 
} 

public void setProduct(String product) { 
    this.product = product; 
} 

public String getWorktype() { 
    return worktype; 
} 

public void setWorktype(String worktype) { 
    this.worktype = worktype; 
} 

public NoteCategory getNoteCategory() { 
    return noteCategory; 
} 

public void setNoteCategory(NoteCategory noteCategory) { 
    this.noteCategory = noteCategory; 
} 

public NoteSubCategory getNoteSubCategory() { 
    return noteSubCategory; 
} 

public void setNoteSubCategory(NoteSubCategory noteSubCategory) { 
    this.noteSubCategory = noteSubCategory; 
} 

public int getNoteId() { 
    return noteId; 
} 

public void setNoteId(int noteId) { 
    this.noteId = noteId; 
} 

public SybaseSqlDao getSybaseDao() { 
    return sybaseDao; 
} 

public void setSybaseDao(SybaseSqlDao sybaseDao) { 
    this.sybaseDao = sybaseDao; 
} 

public List<SelectItem> getSelectWorktypes() { 
    selectWorktypes.clear(); 

    worktypeList = this.getWorktypeList(); 

    for (String strt : worktypeList) { 

     SelectItem si = new SelectItem(); 
     si.setValue(strt); 
     si.setLabel(strt); 
     si.setDescription(strt); 
     selectWorktypes.add(si); 
    } 

    return selectWorktypes; 
} 

public void setSelectWorktypes(List<SelectItem> selectWorktypes) { 

    this.selectWorktypes = selectWorktypes; 
} 

public List<String> getWorktypeList() { 

    worktypeList = sybaseDao.selectWorktypes(); 
    return worktypeList; 
} 

public void setWorktypeList(List<String> worktypeList) { 
    this.worktypeList = worktypeList; 
} 

public List<Product> getProductList() { 

    productList = sybaseDao.selectProducts(); 
    return productList; 
} 

public void setProductList(List<Product> productList) { 
    this.productList = productList; 
} 

public List<SelectItem> getSelectProducts() { 
    selectProducts.clear(); 

    productList = this.getProductList(); 

    for (Product prod : productList) { 

     SelectItem si = new SelectItem(); 
     si.setValue(prod); 
     si.setLabel(prod.toString()); 
     si.setDescription(prod.toString()); 
     selectProducts.add(si); 
    } 

    return selectProducts; 
} 

public void setSelectProducts(List<SelectItem> selectProducts) { 
    this.selectProducts = selectProducts; 
} 

public void processValueChange(ValueChangeEvent arg0) { 

    if (arg0.getComponent().getId().equalsIgnoreCase("productList")) { 
     this.setProduct(arg0.getNewValue().toString()); 

    } 
    if (arg0.getComponent().getId().equalsIgnoreCase("worktypeList")) { 
     this.setWorktype(arg0.getNewValue().toString()); 
    } 

} 

} 

面S-config.xml中

<?xml version="1.0"?> 

<!DOCTYPE faces-config PUBLIC 
    "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" 
    "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> 

<faces-config> 

<lifecycle> 
    <phase-listener> 
     <package>.utils.NoCachePhaseListener 
    </phase-listener> 
</lifecycle> 

<managed-bean> 
    <managed-bean-name>pc_userBacker</managed-bean-name> 
    <managed-bean-class> 
     <package>.web.backer.UserBacker 
    </managed-bean-class> 
    <managed-bean-scope>session</managed-bean-scope> 
</managed-bean> 

<managed-bean> 
    <managed-bean-name>pc_noteCategoryListBacker</managed-bean-name> 
    <managed-bean-class> 
     <package>.web.backer.note.NoteCategoryListBacker 
    </managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

<managed-bean> 
    <managed-bean-name> 
     pc_noteSubCategoryListBacker 
    </managed-bean-name> 
    <managed-bean-class> 
     <package>.web.backer.note.NoteSubCategoryListBacker 
    </managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

<managed-bean> 
    <managed-bean-name>pc_noteListBacker</managed-bean-name> 
    <managed-bean-class> 
     <package>.web.backer.note.NoteListBacker 
    </managed-bean-class> 
    <managed-bean-scope>session</managed-bean-scope> 
</managed-bean> 

<managed-bean> 
    <managed-bean-name>pc_statusListBacker</managed-bean-name> 
    <managed-bean-class> 
     <package>.web.backer.status.StatusListBacker 
    </managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

<managed-bean> 
    <managed-bean-name>pc_statusReasonBacker</managed-bean-name> 
    <managed-bean-class> 
     <package>.web.backer.status.StatusReasonBacker 
    </managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 


<!-- Notes --> 
<navigation-rule> 
    <from-view-id>/jsp/notes/notes.jsp</from-view-id> 
    <navigation-case> 
     <from-action>#{pc_noteListBacker.edit}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/notes/noteedit.jsp</to-view-id> 
    </navigation-case> 
    <navigation-case> 
     <from-action>#{pc_noteListBacker.insert}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/notes/notenew.jsp</to-view-id> 
    </navigation-case> 


</navigation-rule> 


<!-- Note Categories --> 
<navigation-rule> 
    <from-view-id>/jsp/notes/notecategories.jsp</from-view-id> 
    <navigation-case> 
     <from-action>#{pc_noteCategoryListBacker.edit}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/notes/notecategoryedit.jsp</to-view-id> 
    </navigation-case> 
    <navigation-case> 
     <from-action> 
      #{pc_noteCategoryListBacker.insert} 
     </from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/notes/notecategorynew.jsp</to-view-id> 
    </navigation-case> 


</navigation-rule> 

<!-- Note Subcategories --> 
<navigation-rule> 
    <from-view-id>/jsp/notes/notesubcategories.jsp</from-view-id> 
    <navigation-case> 
     <from-action> 
      #{pc_noteSubCategoryListBacker.edit} 
     </from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/notes/notesubcategoryedit.jsp</to-view-id> 
    </navigation-case> 
    <navigation-case> 
     <from-action> 
      #{pc_noteSubCategoryListBacker.insert} 
     </from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/notes/notesubcategorynew.jsp</to-view-id> 
    </navigation-case> 
</navigation-rule> 

<!-- Statuses --> 
<navigation-rule> 
    <from-view-id>/jsp/statuses/statuses.jsp</from-view-id> 
    <navigation-case> 
     <from-action>#{pc_statusListBacker.edit}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/statuses/statusedit.jsp</to-view-id> 
    </navigation-case> 
    <navigation-case> 
     <from-action>#{pc_statusListBacker.insert}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/statuses/statusnew.jsp</to-view-id> 
    </navigation-case> 
</navigation-rule> 

<!-- Status Reasons --> 
<navigation-rule> 
    <from-view-id>/jsp/statuses/statusreasons.jsp</from-view-id> 
    <navigation-case> 
     <from-action>#{pc_statusReasonBacker.edit}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/statuses/statusreasonedit.jsp</to-view-id> 
    </navigation-case> 
    <navigation-case> 
     <from-action>#{pc_statusReasonBacker.insert}</from-action> 
     <from-outcome>success</from-outcome> 
     <to-view-id>/jsp/statuses/statusreasonnew.jsp</to-view-id> 
    </navigation-case> 
</navigation-rule> 

<!-- static and general actions--> 
<!-- what page the action is coming from doesn't matter here --> 
<navigation-rule> 

    <navigation-case> 
     <from-outcome>login</from-outcome> 
     <to-view-id>/login.jsp</to-view-id> 
    </navigation-case> 

    <navigation-case> 
     <from-outcome>menu</from-outcome> 
     <to-view-id>/menu.jsp</to-view-id> 
    </navigation-case> 

    <!-- Notes --> 
    <navigation-case> 
     <from-outcome>notes</from-outcome> 
     <to-view-id>/jsp/notes/notes.jsp</to-view-id> 
    </navigation-case> 


    <!-- Note Categories --> 
    <navigation-case> 
     <from-outcome>notecategories</from-outcome> 
     <to-view-id>/jsp/notes/notecategories.jsp</to-view-id> 
    </navigation-case> 

    <!-- Note Subcategories --> 
    <navigation-case> 
     <from-outcome>notesubcategories</from-outcome> 
     <to-view-id>/jsp/notes/notesubcategories.jsp</to-view-id> 
    </navigation-case> 

    <!-- Statuses --> 
    <navigation-case> 
     <from-outcome>statuses</from-outcome> 
     <to-view-id>/jsp/statuses/statuses.jsp</to-view-id> 
    </navigation-case> 



    <!-- Status Reasons --> 
    <navigation-case> 
     <from-outcome>statusreasons</from-outcome> 
     <to-view-id>/jsp/statuses/statusreasons.jsp</to-view-id> 
    </navigation-case> 


</navigation-rule> 
</faces-config> 

回答

1

我只低頭的代碼,但我想這個問題的那部分可能是在這裏:

public void processValueChange(ValueChangeEvent arg0) { 
     if (arg0.getComponent().getId().equalsIgnoreCase("productList")) { 
       this.setProduct(arg0.getNewValue().toString()); 

     } 
     if (arg0.getComponent().getId().equalsIgnoreCase("worktypeList")) { 
       this.setWorktype(arg0.getNewValue().toString()); 
     } 
} 

如果你讀了valueChangeListener的文檔type屬性,它表示:

要創建和註冊的ValueChangeListener的完全限定Java類名稱。

這意味着至少有三個<package>.web.backer.note.NoteListBacker實例 - 兩個創建爲偵聽器,第三個創建爲託管bean。最後一個是表綁定的唯一一個,並且監聽器中的任何狀態更改都是不相關的。

要解決:

  1. 不要有NoteListBacker實現ValueChangeListener;無關緊要。
  2. 任一屬性綁定selectOneMenuvalueChangeListener#{pc_noteListBacker.valueChange}方法(詳見DOC)OR有一個單獨的ValueChangeListener執行直接從使用FacesContext會話查找pc_noteListBacker
+0

我在第一選擇去(2)(以下在你的建議後,(1)),但我不太能夠按照你的建議是什麼。 我不知道我的困難與另一個問題有關,即頁面上的按鈕(如「添加」)無法正常工作。 – Timbuck 2009-10-19 23:17:57

+0

我描述的問題是,將作爲偵聽器創建的'NoteListBacker'的兩個副本不會影響會話中的NoteListBacker的狀態,該會話是綁定到該表的一個。如果您在表單中遇到問題,請添加一個''標籤 - 它應該顯示任何阻止操作被觸發的問題。 – McDowell 2009-10-20 09:05:55

1

我經常碰到這個,直到我知道這裏有什麼問題。在提交頁面時,JSF將在您調用processValueChange()之後的UPDATE_MODEL階段中運行。所以對BackingBean的更改將被HTTP請求中的值覆蓋,並且不起作用。

爲了防止發生這種情況,您必須在您的ValueChangeListener中手動發佈導航大小寫。您可以通過在processValueChange()的末尾插入以下行來完成此操作。

FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(
       FacesContext.getCurrentInstance(), null, "stay_here"); 

「stay_here」 是指導航的情況下在你的faces-config.xml中

<!-- Notes --> 
<navigation-rule> 
     <from-view-id>/jsp/notes/notes.jsp</from-view-id> 
     <navigation-case> 
       <from-action>#{pc_noteListBacker.edit}</from-action> 
       <from-outcome>success</from-outcome> 
       <to-view-id>/jsp/notes/noteedit.jsp</to-view-id> 
     </navigation-case> 
     <navigation-case> 
       <from-action>#{pc_noteListBacker.insert}</from-action> 
       <from-outcome>success</from-outcome> 
       <to-view-id>/jsp/notes/notenew.jsp</to-view-id> 
     </navigation-case> 
     <navigation-case> 
       <from-outcome>stay_here</from-outcome> 
       <to-view-id>/jsp/notes/notes.jsp</to-view-id> 
     </navigation-case> 

</navigation-rule> 

希望這有助於。

問候