2009-10-19 47 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> 

希望这有助于。

问候