2011-03-21 27 views
1

我想在用戶鍵入inputText字段時生成selecOneMenu內容,並響應組合框選擇更改。
下面的代碼會在用戶鍵入時更新selecOneMenu的內容。 (鍵入的和接下來的9個數字被添加到組合框中,這只是一個簡化的示例代碼。)
加載頁面時,selecOneMenu的更改事件被正確觸發。 但是,在輸入inputValue字段後,selecOneMenu的內容會更改,並且在選擇某個項目時不會觸發更改事件。PrimeFaces p:ajax event =「change」未在動態創建的selecOneMenu內容上觸發

如果ComboBean是會話作用域,代碼將起作用,但如果可能,我希望避免此解決方案。

完全可以這樣做嗎?
如果請求範圍不可能,原因是什麼?

PrimeFaces 2.2
鑽嘴魚科2.0.2
的GlassFish 3.0.1
瀏覽器:瀏覽器,Firefox,IE

combo.xhtml:

<h:head> 
    <title>Combo box example</title> 
</h:head> 

<h:body> 
    <h:form> 
     <p:panel id="mainPanel"> 
      <h:panelGroup id="formToSubmit" layout="block"> 
       <p:messages id="messages" /> 
       <h:panelGrid columns="2"> 
        <h:outputLabel value="Enter a number" /> 
        <h:inputText id="inputValue" value="#{comboBean.inputValue}"> 
         <p:ajax event="keyup" update="combo" 
          listener="#{comboBean.onKeyUp}" /> 
        </h:inputText> 

        <h:outputLabel value="Select a value:" /> 
        <h:selectOneMenu id="combo" value="#{comboBean.selectedValue}"> 
         <f:selectItem itemLabel="Select a value..." 
          noSelectionOption="true" /> 
         <f:selectItems value="#{comboBean.values}" /> 
         <p:ajax event="change" update="selectedValue" 
          listener="#{comboBean.valueSelected}" /> 
        </h:selectOneMenu> 
        <h:outputLabel value="Selected value:" /> 
        <h:inputText id="selectedValue" value="#{comboBean.selectedValue}" /> 
       </h:panelGrid> 
      </h:panelGroup> 
     </p:panel> 
    </h:form> 
</h:body> 
</html> 

ComboBean.java

package x; 

import java.io.Serializable; 
import java.util.LinkedList; 
import java.util.List; 

import javax.annotation.PostConstruct; 
import javax.enterprise.context.RequestScoped; 
import javax.enterprise.context.SessionScoped; 
import javax.inject.Named; 

@Named 
@RequestScoped 
public class ComboBean implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 
    private String inputValue; 
    private String selectedValue; 
    private List<String> values; 

    @PostConstruct 
    void init() 
    { 
     System.out.println("init"); 
     setValues(new LinkedList<String>()); 
     for(int i = 0; i<10 ; i++) 
     { 
      getValues().add(""+i); 
     } 
    } 

    public void onKeyUp() 
    { 
     System.out.println("onkeyUp " + getInputValue()); 
     setValues(new LinkedList<String>()); 
     if (inputValue != null) 
     { 
      try 
      { 
       int v = Integer.parseInt(inputValue); 
       for(int i = 0; i<10 ; i++) 
       { 
        getValues().add(""+(v+i)); 
       } 
      } 
      catch (NumberFormatException ne) 
      { 
       //doesn't matter 
      } 
     } 
    } 

    public void valueSelected() 
    { 
     System.out.println("valueSelected " + getSelectedValue()); 
    } 

    public void submit() 
    { 
     System.out.println("submit " + getInputValue()); 
    } 

    public void setInputValue(String inputValue) 
    { 
     this.inputValue = inputValue; 
    } 

    public String getInputValue() 
    { 
     return inputValue; 
    } 

    public void setSelectedValue(String selectedValue) 
    { 
     this.selectedValue = selectedValue; 
    } 

    public String getSelectedValue() 
    { 
     return selectedValue; 
    } 

    public void setValues(List<String> values) 
    { 
     this.values = values; 
    } 

    public List<String> getValues() 
    { 
     return values; 
    } 

} 

回答

3

問題是,您在init()方法中的每個請求期間重置您的列表。所以你選擇的元素將不再存在。

如果您不想使用SessionScope,那麼ViewScope可能是一個解決方案:那麼如果重新加載相同的頁面,則不會重置bean。

+0

嗨馬特,謝謝你的回答。不幸的是,這是一個CDI bean,我們沒有ViewScope。另一方面,如果我們使用託管bean,我們不能使用@Inject註釋(對不起,代碼太簡單:))。 – Hesi 2011-03-21 12:33:49

+0

也許你可以只將LinkedList放入SessionState中並從RequestScoped bean中引用它? – 2011-03-21 13:02:17

+0

它似乎工作!謝謝! – Hesi 2011-03-21 14:19:07

相關問題