2014-05-05 38 views
1

我有一個包含基於查詢參數(例如,usernamepagenum)填充的dataTable的頁面。表格中的每個條目都有一個刪除命令按鈕從JSF Datatable上的Request Scope Bean中刪除

pagenum != 0和我們單擊刪除時,將在「應用」階段生成要顯示的記錄列表。在這個階段沒有設置視圖參數,所以記錄列表是空的,所以沒有被刪除(我們的刪除方法沒有被調用)

要解決這個問題,我添加了一個@PostConstruct方法,查詢來自Servlet請求的參數並設置bean中的值,所以當我們獲取離開記錄列表時它們是可用的,這允許我的delete方法被調用。

我確定JSF有更好的方式來處理這種情況,而解決方法是一種破解。

實現此方案的正確方法是什麼,無需訴諸View或Session範圍的bean?

當然,必須有一種方法,只需發佈​​表單並刪除相應的記錄,而不必浪費時間來重新生成記錄列表。

+2

爲什麼你不想爲你的bean使用'@ ViewScoped'? '@ SessionScoped'不適合這種情況。 –

+2

你可以發佈你的代碼片?正如@LuiggiMendoza所說,最簡單的方法是使用'@ ViewScoped',這將使您能夠維護表的狀態。 –

+0

在這種情況下,它與服務器中的狀態(如'@ ViewScoped' bean)存儲狀態並不矛盾。如果我沒有使用JSF,那麼很容易在每條記錄上實現一個表單,當提交時會調用合適的代碼來刪除記錄,而不必在服務器上維護任何會話狀態。幫助我理解爲什麼使用'@ ViewScoped' bean是一件好事。如果用戶加載頁面,去吃午飯,提交一個刪除表單,但會話已過期,會發生什麼? –

回答

3

什麼是正確的方式來實現這種情況下,而不訴諸視圖或會話作用域bean?當然必須有辦法只是張貼的形式,並刪除相應的記錄,而不必浪費時間再生的記錄

對不起名單,也沒有辦法。至少不要在標準<h:dataTable>內使用標準<h:commandButton>。這是JSF有狀態的結果。 JSF只是希望確保在處理回發期間和在生成HTML輸出期間視圖完全一樣。

這是JSF針對篡改請求的保護措施的一部分,其中最終用戶/黑客可以以可能危險的方式操縱請求參數,例如,更改要刪除的條目的ID或繞過rendered屬性等的檢查無論如何,如果JSF沒有爲你做這件事,而且很容易被首發者忽視(那麼他們會責怪JSF不安全,而不是自己),所有這些事情你/你應該做額外的預先驗證。另見Why JSF saves the state of UI components on server?commandButton/commandLink/ajax action/listener method not invoked or input value not updated

<h:commandButton>內部<h:dataTable>情況下,JSF簡單地需要具有在應用請求值階段可用的數據模型,以便它可以遍歷組件樹的<h:dataTable>,以便找到被按壓的按鈕和隊列的動作事件。如果沒有數據模型,則無法找到按下的按鈕,並且操作事件不會排隊。通常,這要通過將託管bean放入JSF視圖範圍來解決。另請參見​​

對於請求範圍的Bean,<f:viewParam>確實不適用於在應用請求值階段發生之前保留數據模型的工作。您需要改爲使用@PostConstruct註釋的方法來完成這項工作。 JSF託管的bean可以通過@ManagedProperty注入請求參數。另見ViewParam vs @ManagedProperty(value = "#{param.id}")。在CDI或Spring管理的bean的情況下,沒有可用於將HTTP請求參數注入爲bean屬性的標準註釋。對於CDI,JSF實用程序庫OmniFaces具有@Param的目的。另見OmniFaces @Param showcase。對於春天來說,你需要自己親自生長。我,因爲non-Spring-user不知道該怎麼做。谷歌似乎也沒有透露太多。

或者,你也可以僅僅通過@ViewScoped把豆在視圖範圍。只要您回傳到相同的視圖,它就會生活。 JSF 2.2對於javax.faces.view包中的CDI兼容註釋。 javax.faces.bean包中的包是@ManagedBean的舊JSF 2.0/2.1註釋。 Spring對此沒有任何註釋,因爲它會依賴於JSF API。你需要自己親自生長。 Google顯示severalexamples

1

什麼是實現該場景

支持bean執行任何邏輯之前,正確的方法,JSF 總是必須重建視圖,以獲取有關如何執行的信息。爲了顯示和更新目的,最好的(和正確的)解決方案肯定是@ViewScoped

而不訴諸視圖或會話範圍的bean?

如果你堅持要用@RequestScoped,我會說有真不是正確方式,但變通或黑客。一種方法是像你剛纔提到的那樣用@PostConstruct方法初始化列表。另一種方式可能是爲您的刪除按鈕的onclick屬性使用JavaScript函數。例如,JS函數將使用URL調用服務器來請求刪除。否則,您也可以使用PrimeFace's RemoteCommand作爲JS函數。