目前,我正在更深入地了解JSF 2.0,并且缺乏对托管Bean属性从一个视图到另一个视图的“传输”的了解。我进行了搜索,但没有找到一个很好的例子,因此,如果有人可以将我指向教程或对事情进行一些解释,我将不胜感激。
所以这是我的情况:
我正在开发一个小型游乐场日历应用程序。第一个视图select.xhtml
包含日历选择器,用户可以在其中选择特定日期:
<html>
...
<h:form>
<!-- Calendar selector from primefaces -->
<p:calendar value="#{calendarSelect.date}" mode="inline" navigator="true" />
<p:commandButton value="Show entries for date" action="day" />
...
我相应的支持bean如下所示:
@ManagedBean(name="calendarSelect")
@RequestScoped
public class CalendarSelectComponent {
private Date date = null;
... // Getters and setters
现在,当我从
select.xhtml
提交表单时,我将被转发到day.xhtml
<html>
...
<h:form>
The current day ist:
<h:outputText value="#{calendarEdit.date}">
<f:convertDateTime pattern="dd.MM.yyyy" />
</h:outputText>
支持bean现在看起来像这样:
@ManagedBean(name="calendarEdit")
@ViewScoped
public class CalendarEditComponent implements Serializable {
private Date date = null;
private CalendarEntryBean currentEntry = null;
private List<CalendarEntryBean> allEntries = null;
....
我现在正在尝试解决问题:如何将
date
参数从选择器传输到编辑器?我尝试了多种选择,其中一种是:
<p:commandButton value="Show entries for date" action="day" />
<f:setPropertyActionListener target="#{calendarEdit.date}" value="#{calendarSelect.date}" />
</p:commandButton>
调试器显示,的确,
date
的calendarEdit
属性填充了calendarSelect
中的值,但是由于day.xhtml
是一个新视图,因此将创建一个新的CalendarEditComponent
支持bean,而不是我使用该日期中的日期填充的bean。 select
视图中的选择器。我已经读过一种解决方案是创建一个保留所有值的
SessionScoped
支持bean。但这不是我认为应该起作用的方式,因为我确实不需要会话中的信息,我只是希望它从A到B“旅行”。基于会话的方法的另一个缺点是我可以每个会话只能使用一个选择器和一个编辑器-如果您想到多窗口浏览等等,我认为这是不可接受的。我真的不认为我是遇到这种情况的第一个人,并且我敢肯定JSF为此提供了一个优雅的解决方案,但是我找不到该解决方案。
再一次,如果有人知道如何解决这个问题-我在听! ;-)
最佳答案
<f:setPropertyActionListener>
在表单提交的调用操作阶段执行。因此,它希望那时的价值仍然存在。但是由于您的选择bean是请求范围的,因此在表单提交期间不再存在。相反,您希望传递一个请求参数,该参数在渲染响应期间内联到输出中。您可以使用<f:param>
做到这一点。
<p:commandButton value="Show entries for date" action="day" />
<f:param name="date" value="#{calendarSelect.dateAsString}" />
</p:commandButton>
它可以作为请求参数使用(请注意,由于HTTP的特性,它只能理解字符串)。您可以让JSF将请求参数设置为托管属性,但是由于您的编辑bean是视图作用域的,因此
@ManagedProperty
是不可能的。您必须自己通过ExternalContext
收集它。String dateAsString = externalContext.getRequestParameterMap().get("date");
是的,那很笨拙。我将为此使用相同的bean和视图,并通过
rendered
属性切换选择/编辑表单的可见性。毕竟,编辑视图不能通过简单的GET直接打开/添加书签,不是吗? ;)