2011-08-27 62 views
2

我有一個JSF頁面,用戶可以在其中輸入他們的車到我的數據庫。形式有三個輸入字段:對話範圍意外行爲

  • 廠商
  • 模型
  • 登記

ManufacturerModel字段都是自動完成的字段。爲了完成Model字段,我需要知道用戶在提交表單之前在Manufacturer字段中選擇了什麼值。爲此,我成立了一個AJAX調用通知選定值的託管bean:

<p:autoComplete id="manufacturer" 
       minQueryLength="3" 
       completeMethod="#{carController.complete}" 
       forceSelection="true"> 
    <p:ajax event="itemSelect" 
      listener="#{carController.manufacturerSelected}" /> 
</p:autoComplete> 

而在託管bean:

public void manufacturerSelected(SelectEvent se) { 
    manufacturer = se.getObject().toString(); 
} 

該模型的外觀自動完成場和處理方法大致相同,價值略有不同。

要保留在多個XHR請求manufacturer價值,我已經設置了bean來ConversationScoped,並開始在@PostConstruct標註的方法談話:

@Named 
@ConversationScoped 
public class CarController implements Serializable { 

@Inject 
private Conversation conversation; 

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

什麼我希望是bean只得到實例化一次因爲對話尚未結束,並保留manufacturer字段中的值。但是,這並不適用,並且對於每個XHR請求再次實例化bean,導致manufacturer字段也爲null。在PostConstruct方法中設置斷點顯示它實際上已被調用,方法manufacturerSelected也是如此。

我懷疑這與我沒有手動傳播對話ID的事實有關,但文檔說這個ID應該自動傳播任何faces請求。這實際上是否正確,這是否意味着XHR請求不一定是面對請求?

編輯:在豆的不同位置設置斷點透露,每個XHR請求有一個新的bean(conversation.getId()不斷變化),所以我顯然不傳播正確的ID。如何用p:ajax傳播ID,我可以在哪裏用EL獲得它?

+0

雖然對話可能不是這裏的方法,但您可以通過例如firebug或burpproxy調試實際的ajax請求,以查看真正發送的內容。 –

回答

1

由於您沒有真正使用對話(至少在您提供的示例中沒有),爲什麼不使用視圖範圍呢?這將完全符合你的要求,而無需傳播對話ID的開銷。

請注意,要使@ViewScoped正常工作,必須將bean更改爲JSF託管bean(刪除@Named)。這是由於Java EE 6中的設計bug/spec監督造成的。如果您想繼續使用CDI,那麼可以使用Seam 3提供的Java EE 6擴展來修復此錯誤。

+0

哎唷,這很重要。我閱讀了組件綁定並最終使用了,而不是將輸入字段綁定到託管bean中的字符串值,將其綁定到HtmlInputText並對其執行getValue(),這似乎起作用。不管怎麼說,還是要謝謝你! – Laurens

+0

這不是一個規範監督。 JSF在CDI之前完成。它目前不適用於Seam 3(Seam-Faces)。關於它的一個有趣的線索和它的一個替代方案是例如在http://forum.primefaces.org/viewtopic.php?f=3&t=7585 –

+0

是的,JSF早些時候完成了,但Java EE 6整體上不應該只是將各個規範捆綁在一起,而是要確保它們一起工作並不衝突。另外,由於JSF較早完成,CDI有時間以某種方式集成@ViewScoped。 –

0

是。這是JSF 2和Primefaces一起不傳播對話ID的問題。您可以嘗試下面的解決方法。 (這是由於相同的問題,其他誰將在這裏結束)。

<p:autoComplete id="manufacturer" 
      minQueryLength="3" 
      completeMethod="#{carController.complete}" 
      forceSelection="true" onchange="updateManufacturer([{name:'cid',value:'#{javax.enterprise.context.conversation.id}'}])"> 
</p:autoComplete> 
<p:remoteCommand name="updateManufacturer" action="#{carController.manufacturerSelected}" 
           process="manufacturer" />