【发布时间】:2018-10-08 17:53:39
【问题描述】:
我正在试验 JSF 范围,但在请求范围 bean 中使用会话范围 bean 时遇到了一些问题。
基本工作流程是用户从主页单击项目上的查看按钮,然后调用我的代码来加载和显示该项目的信息。
这是我的更新代码:
@ManagedBean(name="itemViewBean")
@RequestScoped
class ItemViewBean {
@ManagedProperty("#{itemBean}")
private ItemBean itemBean;
private ItemViewObject itemViewObject;
private int itemId;
public void init() {
itemViewObject = itemBean.readItem(itemId);
}
public String readItem(int itemId) {
// itemViewObject = itemBean.readItem(itemId); // moved to init();
return "/pages/viewItem.xhtml?faces-redirect=true";
}
public ItemViewObject getItemViewObject() {
return itemViewObject;
}
// getters & setters as needed
}
@ManagedBean(name="itemBean")
@SessionScoped
class ItemBean {
public ItemViewObject readItem(int itemId) {
// hardcoded creating a ItemViewObject for now.
// eventually would be loaded from the database.
....
}
}
我的 UPDATED 视图页面有如下内容:
<!-- added the metadata -->
<f:metadata>
<f:viewParam name="id" value="#{itemViewBean.itemId}" />
<f:event listener="#{itemViewBean.init}" type="preRenderView" />
</f:metadata>
<!-- same as before -->
<h:outputText value="#{itemViewBean.itemViewObject.description}" />
如果我的 viewBean 是请求范围的(或视图范围的),我会在视图页面上得到空数据。如果 viewBean 是会话范围的,那么一切正常。我不明白为什么?
从我在调试器中看到的情况来看,readItem(itemId) 被调用(从主页单击视图按钮时),但是当视图页面本身调用 getItemViewObject() 时,itemViewObject 为空。
我做错了什么?
更新 我之前忘了提到我的主页是如何调用 readItem 方法的,那是通过一个命令按钮:
<h:commandButton class="btn btn-mini firefoxBtnMiniCorrection"
value="View"
action="#{itemViewBean.readItem(b.itemId)}"/>
主页中列出的每个项目都有自己的查看按钮。
还忘了提到主页和我的视图页面都使用 JSF 模板。我不知道这是否重要。
从人们制作的下面的 cmets 中,我想出了上面的代码更改。现在一切正常。现在可以对 ItemViewBean 使用请求范围或视图范围。
我很惊讶这能奏效!我不太确定我是否完全理解它的工作原理。
我的更改是正确的做事方式吗?还是有更好的办法?
另外,我使用的是 JSF 2.1。
更新 2 它不起作用。范围界定有效,但我发现 viewParam 中的 itemId 始终为空。为什么?
【问题讨论】:
-
我个人不太喜欢这种流。为什么你真的需要在会话中有这种数据?如果要为特定视图显示它,只需将其加载到
@ViewScopedbean 中。为视图加载初始数据的方法应该称为through af:viewActionbinding,这样可以确保它只被调用一次,从而不会对数据库进行不必要的调用。 -
@XtremeBiker 谢谢。根据您发布的帖子,以及查看 BalusC 的一篇文章,我更新了上面的代码。一切正常。有没有其他方法或更好的方法来做到这一点?再次感谢!
-
这是我正在查看的来自@BalusC 的article。