2011-08-25 70 views
2

我有一個叫做trip.xhtml,我帶出來的參數使用下面的代碼的URL的網頁:查看參數

<f:metadata> 
    <f:viewParam name="tripid" value="#{tripBean.tripId}" /> 
    <f:viewParam name="seats" value="#{tripBean.seats}" /> 
    <f:event type="preRenderView" listener="#{tripBean.processParams}" /> 
</f:metadata> 

TripBean看起來像這樣(簡化):

@ManagedBean 
@RequestScoped 
public class TripBean implements Serializable { 

    private static final long serialVersionUID = -4885781058258859229L; 

    private Long tripId; 
    private int seats; 

    // Getters and setters for tripId and seats 

trip.xhtml頁面的底部我有一個h:link

<h:link outcome="/customer/booking.xhtml" value="Book this trip" 
    includeViewParams="true" /> 

我期望的是當我點擊這個鏈接時,我得到的URL就像"/customer/booking.jsf?tripid=2&seats=1"。這是隻有當我把下面的代碼我booking.xhtml頁面上的情況:

<f:metadata> 
    <f:viewParam name="tripid" value="#{tripBean.tripId}" /> 
    <f:viewParam name="seats" value="#{tripBean.seats}" /> 
</f:metadata> 

雖然我其實想是用另外一個bean。代碼更改爲:

<f:metadata> 
    <f:viewParam name="tripid" value="#{bookingBean.tripId}" /> 
    <f:viewParam name="seats" value="#{bookingBean.seats}" /> 
</f:metadata> 

BookingBean也有2個屬性tripIdseats這是相同的TripBean,但是當我嘗試點擊現在的聯繫,我只看到它被設置爲0個席位參數("/customer/booking.jsf?seats=0"

有沒有人有任何想法,當我試圖使用另一個bean來存儲它們時,爲什麼我不能將viewparams傳遞到另一個頁面?如果不能將它存儲在另一個bean中,我怎麼能把TripBean中的那些值放在BookingBean

我使用的快速解決方法: 不使用includeViewParams="true",但手動向鏈接添加參數(參見下文)「修復」問題。雖然我仍然想知道爲什麼它不適用於includeViewParams

<h:link outcome="/customer/booking.xhtml" value="#{msg['page.trip.booking']}"> 
    <f:param name="tripid" value="#{tripBean.tripId}" /> 
    <f:param name="seats" value="#{tripBean.seats}" /> 
</h:link> 

回答

1

鏈接內容對應於以下標記:

<h:link outcome="/customer/booking.xhtml" value="Book this trip" 
      includeViewParams="true" /> 

過程中爲trip.xhtml視圖請求的渲染響應階段中產生。如果您需要URL來包含視圖參數值,則必須在用於訪問視圖的URL中提供這些值,或者您必須在呈現響應階段完成之前在模型中設置這些值。如果您不執行其中任何一項,則生成的超鏈接將包含視圖參數的默認值。

在簡單的話,你必須:

  • 要麼確保trip.xhtml觀點與必要的參數訪問:​​,特別是如果觀點是在任何時候的參數進行訪問。
  • 或者您必須設置JSF運行時呈現鏈接之前執行的方法中的值。類中的BookingBean類或@PostConstruct註釋方法的構造函數將是設置值的理想位置。在視圖中執行操作的情況下,您還可以重置/更新託管bean的其他方法中的bean值。請注意,JSF運行時將調用getTripIdgetSeats以將視圖參數tripIdseats的值包含在生成的URL中,因此您還應該驗證這些方法的行爲。

你,爲什麼你不能在EL表達式booking.xhtml指定bookingBean,而不是要求你指定的tripBean的所謂意想不到的價值問題是由於一個事實,即link標籤的includeViewParams屬性,將包括​​的參數而不是from-view。簡而言之,JSF運行時將調用bookingBean.getTripId()bookingBean.getSeats()而不是tripBean.getTripId()tripBean.getSeats()。儘管這看起來可能與直覺相反,但您應該明白,JSF規範對待這種情況的方式完全不同。在用戶執行的大多數交互中,組件的操作URL是在用戶執行操作時生成的,而不是在此之前生成的。另一方面,link標籤需要對URL進行搶先計算,因此JSF運行時將其視爲「搶先導航」。在構造URL時,必須可以訪問與目標視圖的視圖參數有關的對象,以使URL有意義。在URL中值爲0的原因是在此評估過程中創建了一個新的BookingBean實例,並且正在使用默認值。通過使用TripBean代替(並且includeViewParams的大多數示例演示了這一點),您可以非常明顯地避免這種情況,或者可以在構建BookingBean對象期間設置值。

+0

trip.xhtml頁面可以獲取參數tripid和座位。如果我理解的很好,參數可以在Apply Request Values階段讀取。這些被放入更新模型值的TripBean中,並且在渲染 - 響應階段生成鏈接。因此,當我將這兩個參數提供給trip.xhtml時,預訂鏈接應該生成正確的,對吧?但是,這似乎只發生在booking.xhtml也使用tripBean來捕獲參數,而不是當我嘗試使用另一個(bookingBean)bean時! – StefK

+0

@Trinorae:你誤解了f:paramView。您描述的行爲完全是它應該如何工作的,這不是一個錯誤或問題,因此它不需要解決方法。 f:paramView不是意味着在兩個bean之間移動值。它旨在保持源與目標相同。這種行爲與其他JSF組件的工作方式是一致的。從任意源生成參數的優雅方式是f:param ...基本上,你試圖將一個精心設計的JSF輕鬆地壓縮成你認爲「好」的錯誤,同時拒絕學習。唷。 – fdreger

+0

我想我誤解了viewParams的使用!感謝您給我啓發。 – StefK

2

f:viewParam的工作方式與h:inputText完全相同。這意味着它使用與源(渲染時)和目標(更新模型時)相同的表達式。如果您有:

<h:inputText value="#{a.test}" /> 

你從來不問「如何從b.foo使inputText讀寫a.test」,但似乎每個人都期望從f:viewParam這種行爲。

無論如何,有一個簡單的答案。要附加任何值鏈接,您只需要使用f:param

<h:link outcome="/customer/booking.xhtml" value="Book this trip" > 
    <f:param name="tripid" value="#{bookingBean.tripId}" /> 
    <f:param name="seats" value="#{bookingBean.seats}" /> 
</h:link> 
+0

我發現這是一個解決方法。但是,在加載trip.xhtml時,您將tripid和座位的值放在tripBean中。您可以使用includeViewParams傳遞viewParams。那麼爲什麼我不能通過鏈接嘗試用另一個bean來捕獲這些參數的值傳遞給另一個頁面? – StefK

+0

@Trinorae:什麼「解決方法」?解決什麼問題? – fdreger

+0

使用f:param而不是includeViewParams屬性 – StefK