2011-10-31 86 views
3

我正在學習如何使用JSF使用事件。出於某種原因,當我更改下拉菜單的值時,程序不會更改文本字段中的值。該頁面加載並顯示「德國」,但不會將文本字段更改爲「DE」。有什麼建議麼?JSF ValueChangeListener不起作用

的index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?> 
<!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"> 
<h:head> 
    <title>Facelet Title</title> 
</h:head> 
<h:body> 
    <f:view> 
     <h:form> 
      <h:selectOneMenu value="#{Bean.selectedItem}" valueChangeListener="#{Bean.changeEvent}" onchange="submit()" > 
       <f:selectItems value="#{Bean.itemsList}" /> 
      </h:selectOneMenu> 
      <br /> 
      <h:inputText value="#{Bean.selectedItem}" /> 
     </h:form> 
    </f:view> 
</h:body> 

MyBean.java

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 
import java.util.ArrayList; 
import javax.faces.model.SelectItem; 
import javax.faces.event.ValueChangeEvent; 
@ManagedBean (name = "Bean") 
@RequestScoped 
public class MyBean { 

private static ArrayList menuItems; 
private String selectedItem = "EN"; 
static { 
    menuItems = new ArrayList(); 
    menuItems.add(new SelectItem("EN", "English")); 
    menuItems.add(new SelectItem("DE", "Germany")); 
} 

public ArrayList getItemsList() { 
    return this.menuItems; 
} 

public void setSelectedItem(String item) { 
    this.selectedItem = item; 
} 

public String getSelectedItem() { 
    return selectedItem; 
} 

public void changeEvent(ValueChangeEvent e) { 
    selectedItem = e.getNewValue().toString(); 
} 

} 
+0

該輸入字段*是否真的需要是輸入字段?它不應該只是只讀或輸出字段嗎? – BalusC

+0

我只是這樣做,以瞭解它是如何工作的。我有另一個更大的程序,我使用它來在選擇時自動輸入默認值。這是爲了測試。我只需要弄清楚如何更改下拉菜單值更改時的文本字段。 – user1011376

回答

13

你基本上濫用valueChangeListener作爲actionListener。值更改偵聽器可以訪問兩個舊的和新的值,正好在新的輸入值被提交和模型值被更新之間,以便您可以例如添加一個關於價值變化。你顯然對舊價值不感興趣。你根本不感興趣的價值變化事件。您只對新模型的價值感興趣。所以你不應該使用值更改監聽器。

通常情況下,您希望在動作偵聽器方法中完成這項工作。您可以使用<f:ajax>定義一個Ajax動作偵聽器:

<h:selectOneMenu value="#{Bean.selectedItem}"> 
    <f:selectItems value="#{Bean.itemsList}" /> 
    <f:ajax execute="@this" listener="#{Bean.changeEvent}" render="input" /> 
</h:selectOneMenu> 
<h:inputText id="input" value="#{Bean.selectedItem}" /> 

public void changeEvent() { 
    selectedItem = selectedItem; 
} 

但既然你已經綁定的輸入屬性相同的下拉菜單中,整個聽衆是多餘的。就在下面應該爲你做:

<h:selectOneMenu value="#{Bean.selectedItem}"> 
    <f:selectItems value="#{Bean.itemsList}" /> 
    <f:ajax execute="@this" render="input" /> 
</h:selectOneMenu> 
<h:inputText id="input" value="#{Bean.selectedItem}" /> 

,你所看到的是,因爲onchange="submit()"本質提交整個形式,包括所有其他輸入字段的問題。由於JSF按順序處理輸入字段,並且已將這兩個字段綁定到相同的屬性,所以值<h:inputText>將覆蓋值<h:selectOneMenu>。根據我對這個問題的評論,當你將它作爲<h:inputText readonly="true"><h:outputText>(這樣它就不會將其值提交給服務器)時,你就不會遇到這個問題。

+0

很好的回答!它幫助我 –

1

更改爲輸出文本組件,看看它是否工作

<h:inputText value="#{Bean.selectedItem}" /> 

<h:outputText value="#{Bean.selectedItem}" /> 

商祺!

+0

工作。它如何在輸入文本字段上不起作用?該程序供用戶選擇其數據庫引擎(MySQL,SQLServer,Oracle,PostgreSQL)。我需要在文本字段中放置一個默認端口,並允許用戶在使用其他端口時編輯該字段。 – user1011376

+0

在這種情況下,您可以嘗試將另一個偵聽器綁定到inputText組件(如onchange)。我強烈推薦使用f:ajax標籤以及上面提到的其他海報。希望這個作品! – Mechkov