2011-11-24 117 views
2

我想修改PrimeFaces展示應用中的示例"ajaxify select",並引入第三個p:selectOneMenu,並根據第二個p:selectOneMenu的選擇進行選擇。3 Ajax的級聯下拉菜單

下面是修改代碼:

<h:form> 
    <p:growl id="msgs" showDetail="true"/> 
    <p:panel header="Double Combo" style="margin-bottom:10px;"> 
     <h:panelGrid columns="3" cellpadding="5"> 
      <p:selectOneMenu id="city" value="#{pprBean.city}"> 
       <f:selectItem itemLabel="Select City" itemValue="" /> 
       <f:selectItems value="#{pprBean.cities}" /> 
       <p:ajax update="suburbs" 
         listener="#{pprBean.handleCityChange}" /> 
      </p:selectOneMenu> 

      <p:selectOneMenu id="suburbs" value="#{pprBean.suburb}"> 
       <f:selectItem itemLabel="Select Suburb" itemValue="" /> 
       <f:selectItems value="#{pprBean.suburbs}" /> 
       <p:ajax update="subsuburbs" 
        listener="#{pprBean.handleSuburbChange}" /> 
      </p:selectOneMenu> 

      <p:selectOneMenu id="subsuburbs" value="#{pprBean.subsuburb}"> 
       <f:selectItem itemLabel="Select Subsuburb" itemValue="" /> 
       <f:selectItems value="#{pprBean.subsuburbs}" /> 
      </p:selectOneMenu> 
     </h:panelGrid> 

     <p:separator /> 

     <p:commandButton value="Submit" update="msgs" 
      actionListener="#{pprBean.displayLocation}"/> 
    </p:panel> 
</h:form> 

但永遠不會執行偵聽器函數#{pprBean.handleSuburbChange}。我在另一個論壇看到,ajax響應中的動態代碼不包含其他tag屬性中的標籤,但我該怎麼做呢?

PPRBean代碼我添加:如果所選擇的項目不能被處理

@Named("pprBean") 
@RequestScoped 
public class PPRBean implements Serializable { 

    // ... 

    public void handleSuburbChange() { 
     if (suburb != null && !suburb.equals("")) { 
      subsuburbs = subsuburbsData.get(suburb); 
     } else { 
      subsuburbs = new HashMap<String, String>(); 
     } 
     log.info("subsuburbs:" + subsuburbs); 
    } 

    // ... 

回答

0

該偵聽器將不被調用。您已將bean放入請求範圍中,這意味着在與請求關聯的響應完成時(即瀏覽器完成加載頁面時)它會被垃圾回收。所以,當你提交表單時,一個新的請求將被觸發,並創建一個全新的bean,在你的情況下,顯然不會在(post)構造器中準備/預填郊區列表以查找所選項目並執行偵聽器)。

要解決這個問題,通常需要將JSF @ViewScoped註釋和@ManagedBean一起放入視圖範圍中。

@ManagedBean 
@ViewScoped 
public class Bean { 
    // ... 
} 

這樣,只要您與相同的視圖交互,bean實例就會存活。但是,由於您使用CDI來管理bean而不是JSF,因此您需要使用@ConversationScoped來代替並自行控制Conversation

@Named 
@ConversationScoped 
public class Bean { 

    @Inject 
    private Conversation conversation; 

    @PostConstruct 
    public void init() { 
     conversation.begin(); 
     // ... 
    } 

    public void submit() { 
     // ... 
     conversation.end(); 
    } 

} 
+0

你確定嗎?在這種情況下,爲什麼第二個SelectOneMenu會填充好值。我試過你的解決方案,但沒有看到改進。不過謝謝你的回答! – user1064716

+0

因爲您使用了ajax,視圖將保持不變,但支持bean不同。如果它仍然不起作用,那麼也許你不是正確更新或使用對話範圍的ajax。它至少對我來說工作得很好。 – BalusC