2013-01-15 21 views
3

試圖用視圖作用域bean包裹我的頭像。請原諒我發佈的時間長度。 我有一個視圖:page1.xhtml,它使用提交表單的bean和commandButton,通過action屬性調用同一個bean的方法。使用視圖作用域bean進行數據交換

該方法的返回值導致導航規則「導航」到page2.xhtml。因此,我的理解是,一旦導航將請求流轉到page2.xhtml,page1.xhtml使用的名爲「player」的bean將超出範圍。畢竟,每個視圖都使用一個名爲「player」的視圖範圍的bean。我需要傳達一個名爲id的參數。所以page1.xhtml有一個元素作爲用於'submit'page1'的commandButton的子元素。

Page2.xhtml使用下列構建體我所需的視圖作用域bean之前page2.xhtml的呈現被加載:

<ui:define name="metadata"> 
    <f:metadata> 
    <f:viewParam name="id" value="#{player.id}" /> 
    <!-- this should cause bean to be loaded before it's needed for initial rendering --> 
    <f:event type="preRenderView" listener="#{player.initFromId}"/> 
    </f:metadata> 
</ui:define> 

在player.initFromId方法,我轉儲出到標準輸出的鍵&由FacesContext.getCurrentInstance()。getExternalContext()。getRequestParameterMap();返回的映射的值。

我看到了什麼? [我從這個列表中刪除了大部分客戶端保存的視圖狀態:-)] 大多數鍵是完全限定的UI組件名稱,按命名組件層次結構命名。好。典型的後NV對...

最後我的問題:我是糾正假設鍵:ID是由於F的存在:param元素作爲命令按鈕的孩子造成的命令按鈕的代碼IMPL推鍵+值到請求參數映射?我希望如此,但我不喜歡假設太多。幾乎總是讓我陷入更深的麻煩。

但f:viewParam不會導致在player.initFromId()之前調用player.setId()方法 - 通過preRenderView事件。 player.initFromId()被調用,但不是setter?

我希望我的假設是正確的,因爲我無法想象它是通過不同視圖/頁面調用的代碼使用UI組件字段名稱的設計目標(在本例中爲page2.xhtml) 。這將緊密結合每個頁面的實現,使外部化的導航規則幾乎毫無意義。我還假設使用f:viewParam和f:param的目標是提供最小的耦合(僅在聲明級別 - page1聲明它提供了一個參數,page2聲明需要參數 - 協議留給框架)。

Player.initFromId - key:id, value:37 
Player.initFromId - key:javax.faces.ViewState, value:H4sIAAAAAA[....]YQfAAA= 
Player.initFromId - key:javax.faces.partial.ajax, value:true 
Player.initFromId - key:javax.faces.partial.execute, value:@all 
Player.initFromId - key:javax.faces.partial.render, value:registrationForm:regPage 
Player.initFromId - key:javax.faces.source, value:registrationForm:SubmitButton 
Player.initFromId - key:registrationForm, value:registrationForm 
Player.initFromId - key:registrationForm:SubmitButton, value:registrationForm:SubmitButton 
Player.initFromId - key:registrationForm:firstName, value:Bob 
Player.initFromId - key:registrationForm:j_idt18:carriers, value:Sprint 
Player.initFromId - key:registrationForm:j_idt18:city, value:Sparta-test4 
Player.initFromId - key:registrationForm:j_idt18:dob_input, value: 
[ many other UI components key+value pairs omitted] 

從page1.xhtml:

<p:commandButton tabindex="0" id="SubmitButton" value="Register" 
    action="#{player.register}" update="regPage" > 
    <!-- this needs to be set after the register() method completes. is that so? --> 
    <f:param name="id" value="#{player.id}"/> 
</p:commandButton> 

非常感謝百忙之中閱讀此發佈過多的時間。

回答

1

你似乎是由前鋒導航。前鋒在渲染響應階段基本上會創建一個新視圖。 <f:viewParam>不會在轉發的請求上運行。它僅在最初的請求上運行(最初由客戶端發起)。您需要通過重定向進行導航而不是前進,以便客戶端將被指示發出全新的GET請求,從而觸發所有的作品。您可以通過添加faces-redirect=true參數導航結果像這樣實現這一目標:

return "page2?faces-redirect=true"; 

然而,這失去當前請求的所有請求參數。所以你需要明確地將它添加到導航結果中:

return "page2?faces-redirect=true&id=" + id; 
+0

會話範圍在這裏適合嗎? – KidTempo

+0

@Kid:取決於具體的功能要求。在OP的情況下,它可能不是。有關選擇正確範圍的更多詳細信息,另見http://stackoverflow.com/questions/7031885/how-to-choose-the-right-bean-scope – BalusC