2013-03-22 31 views
3

好吧我知道範圍問題一直出現,但我對解決方案稍有不同。 @ViewScope@RequestScope@SessionScope之間的夢幻橋樑。在多個視圖中堅持ViewScoped的豆

但是,仍然有一個常見的用例(至少對我來說)我真的不想使用@SessionScope,但我需要通過幾個視圖獲取數據。一個非常簡單的情況是,當我將多個數據表連接在一起時,每個數據表取決於以前的選擇。

完全可以使用<f:paramView>並在地址中傳遞一個或幾個數據段作爲參數,然後再次從數據庫中檢索所有數據。我更感興趣的是找到一種方法來創建beans狀態/變量的「快照」,創建新的@ViewScope,然後將「快照狀態」恢復到新的bean。

這樣的事情是否存在?想法?意見?

回答

2

我不知道這是'接受的解決方案',但我實現了一個適用於我的想法。 (反饋感激!)

所以我創建了一個@SessionScoped類與一對夫婦的靜態地圖:

private static Map<String, Object> objectVariableMap; 

// Getters, setters and methods etc. are omitted for simplicity 

的想法是,我指定的地圖,它接受一個字符串作爲密鑰和對象作爲值。我特別沒有設置對象的類型,以允許我在其中存儲任何對象的類型。需要注意的是,在檢索對象時需要確定對象的類型,以便將其重新轉換爲原始類型。

現在來設置來自第一個@ViewScoped的數據。我生成一個隨機UUID(或任何你想要的)作爲地圖,然後將設置爲我正在使用的對象(即,this,或者其他任何您可能想要傳遞給下一個視圖)。將鍵值保存到映射中,並將URL參數設置爲鍵值。

我從不熱衷於在URL params中傳遞數據(如用戶標識等)(甚至在加密時)。這個想法還有一個好處,即提供具有可指定的使用期限的一次性URL值。

在接收端(即新@ViewScoped豆,或任何其他範圍爲此事),你在URL PARAM讀取(在地圖鍵)使用<f:paramView>,然後使用preRenderView事件來檢索和設置的對象,其中與...合作。

此時,您可以選擇從映射中刪除密鑰對,並使檢索該對象的能力無效,或者如果有任何更改,只需更新對象即可保持密鑰對的持續時間更長。

更新:從概念上說,這是非常成功的(至少對我而言)。我創造了一些有用的方法和類,圍繞着這個概念,使它更具普遍性。如果有人想要更具體的指示,或者我可能會創建一個小圖書館,如果任何人想要的。

1

您可以使用CDI「對話範圍」。這比會話範圍窄,但比視圖範圍更寬。

如果您傳遞參數的頁面是一個單元,您也可以使它們成爲JSF 2.2中的流並使用流作用域。

像CODI這樣的項目提供了各種其他可在頁面之間使用的範圍。

+0

我已經使用了'ConversationScoped',但是我從來沒有和它一起過。它有它的用途,但我最初真的在尋找一種將一個ViewScoped對象傳遞給另一個的方法。 CODI和DeltaSpike(正式的Seams Faces)再次向CDI提供JSF實現。我真的正在尋找一種將範圍內的對象從範圍傳遞到範圍的通用方法。 – tarka 2013-03-23 14:32:07

+0

請求技巧中的導航可以將一個頁面中的內容從一個頁面切換到另一個頁面,但是在地址欄問題中,您將遭遇一個後面的URL。 – 2013-03-25 09:07:47

+0

是的。它有點醜陋,但我也寫了一些JS來用ajax替換頁面的主要內容,並使用html5歷史API來做類似的事情。問題是它不是一個好的用戶體驗。 – tarka 2013-03-25 09:20:42