2012-04-27 28 views
1

我正在處理使用JSF 2.0和Richfaces 4的應用程序,該應用程序由許多顯示元素以及通常的查看/編輯/刪除選項的表組成。經過一些SO瀏覽和谷歌搜索後,我決定發佈一個問題,因爲我發現的答案並沒有解決我的問題。沒有會話bean的屬性的優雅處理

現在,我的應用程序在處理存儲在請求bean中的某些屬性時遇到問題,並且在某些點上由於連續請求而丟失。

例如,當我想要編輯一個對象時,該對象被髮送(f:propertyActionListener)到一個請求bean,該請求bean在表單上顯示數據,然後在請求結束時將其丟棄。保存時,會創建一個新對象,並將表單上的屬性設置爲該對象,並且該項目將被保存而不是更新,因爲它沒有標識(JPA + Hibernate)。

我已經研究過多種選項,這是我到目前爲止已經做了,結果:

F:參數+ H:鏈接或h:commandLink:隨着@ManagedProperty的參數是空,我無法在上下文中找到它來通過JNDI查找它。

f:setPropertyActionListener + h:commandLink + Request Bean: Works ...但我失去了一些數據。顯示數據的表單有一些有條件的呈現字段,我無法保存該信息,因此如果驗證階段發現無效數據,表單就會混亂。

f:viewParam + h:commandLink +查看作用域Bean:這裏有些奇怪的東西。這個不直接工作,因爲bean在呈現表單前似乎被丟棄,因爲表單沒有任何信息,因爲bean是乾淨的。

使用會話bean:工程就像一個魅力,但我不想爲每個表單創建一個會話bean,只是因爲我仍然在學習有關JSF生命週期的事情,我想要做到恰當辦法。

如果我想保持請求會話方法,是否有方法來存儲參數(對象或純字符串)並稍後獲取請求bean ?.

不知道如果這有幫助,但我通過ui使用母版頁:insert和ui:define。

回答

1

使用視圖範圍的bean。它應該工作。您在那裏描述的問題表明您已將其綁定到JSTL標記或idbinding屬性。你不應該在視圖範圍的bean上這樣做。另見@ViewScoped fails in tag handlers。另一個可能的原因是,您正在使用CDI的@Named來管理該Bean,而不是JSF的@ManagedBean。這也可以解釋爲什麼@ManagedProperty在你的嘗試中不起作用,因爲它也要求bean由JSF的@ManagedBean管理。

至於主細節頁面方法,請在表頁面中使用<h:link><f:param>以在主頁面中創建視圖/編輯鏈接。

E.g. user/list.xhtml

<h:dataTable value="#{userList.users}" var="user"> 
    <h:column>#{user.id}</h:column> 
    <h:column>#{user.name}</h:column> 
    <h:column> 
     <h:link value="Edit" outcome="edit"> 
      <f:param name="id" value="#{user.id}" /> 
     </h:link> 
    </h:column> 
</h:dataTable> 

該bean可以只是請求作用域。

然後,在默認頁面(在本例中爲編輯頁面),使用<f:viewParam>轉換,驗證並將id設置爲User

E.g. user/edit.xhtml

<f:metadata> 
    <f:viewParam name="id" value="#{userEdit.user}" 
     converter="#{userConverter}" converterMessage="Bad request. Unknown user." 
     required="true" requiredMessage="Bad request. Please use a link from within the system." /> 
</f:metadata> 

<h:messages /> 
<h:link value="Back to all users" outcome="users" /> 

<h:form id="user" rendered="#{not empty userEdit.user}"> 
    <h:inputText value="#{userEdit.user.name}" required="true" /> 
    ... 

    <h:commandButton value="Save" action="#{userEdit.save}"> 
     <f:ajax execute="@form" render="@form" /> 
    </h:commandButton> 
</h:form> 

使用@ViewScoped bean來保存數據,服務和操作方法:

@ManagedBean 
@ViewScoped 
public class UserEdit { 

    private User user; 

    @EJB 
    private UserService service; 

    public String save() { 
     service.save(user); 
     return "users"; 
    } 

    // Getter+setter. 
} 
+0

即使在這種情況下,是'@ ViewScoped'真是一個很好的解決方案?雖然需要多一點工作,但我通常喜歡使用'@ ConversationScoped'來避免使用後退按鈕,多個選項卡/窗口和視圖範圍數據過期的問題。我需要寫一篇關於我的想法的適當的博客文章,但現在我會引用[先前的答案](http://stackoverflow.com/questions/10098528/jsf-2-0-viewscoped-redirect-navigation-to -target-blank/10108609#10108609)。 – Brian 2012-04-27 13:08:54

+0

感謝您的帖子@BalusC!總是很高興地閱讀你的答案。至於這些選項,我們沒有對您的博客上的鏈接指定的特定標籤進行綁定,也沒有將標籤直接綁定到bean。在「渲染」屬性上使用某些EL表達式可能會導致問題出現?我們會根據具體情況調整表格。 – Gamb 2012-04-27 15:26:11

+0

'@ ViewScoped'是否在基本的Hello World頁面上失敗,只有一個提交按鈕,其中action方法返回'null'或'void'? – BalusC 2012-04-27 16:17:06