在我的应用程序中,我有以下bean:
@Named(value = "mrBean")
@SessionScoped
public class MrBean implements Serializable {
@EJB
private MrsBean mrsBean;
private Item item;
public void updateItem() {
this.item = mrsBean.updateItem(item.getId());
}
}
@Named(value = "itemBean")
@RequestScoped
public class itemBean {
@Inject
private MrBean mrBean;
@PostConstruct
public void init() {
if (FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("update") != null) mrBean.updateItem();
}
}
在显示ViewItem.xhtml
页面上的项目信息之前,我会检查是否提交了update
参数以在显示之前更新项目。
当我使用参数update=true
测试页面时,我不知道为什么渲染旧数据而不是新更新的数据。实际上,我必须在呈现新数据之前刷新页面。
从上面的结果中,我想知道在呈现视图后是否调用了@PostConstruct
方法。
如果你能给我一个建议,我将非常感激。
致以最诚挚的问候,
答案 0 :(得分:2)
如果在 #{itemBean}
之后的视图中第一次引用了#{mrBean.item}
,就会发生这种情况。 E.g。
#{mrBean.item}
...
#{itemBean}
当EL表达式首次引用它时,第一次构造托管bean,但它尚未在范围内存在。在GET请求中,其中托管bean实例未被taghandler属性或f:event
引用,那么它只会在呈现响应期间构建。
如果重新排列它们以便在引用 #{itemBean}
之前始终引用(并因此构造) ,那么最好使{{1} } #{mrBean.item}
@PostConstruct
代替。{/ p>
#{itemBean}
答案 1 :(得分:1)
我正在发布另一种解决方案,以防它对您有所帮助。您可以通过在每次要呈现页面时调用初始化方法来尝试不同的方法,并避免让请求bean进行更新。将此元数据标记添加到xhtml:
<f:metadata>
<f:event type="preRenderView" listener="#{mrBean.init}" />
</f:metadata>
在你的MrBean中,定义这个方法:
public void init() {
if(!FacesContext.getCurrentInstance().isPostback() && FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("update") != null)
mrBean.updateItem();
}
这样,每次呈现ViewItem页面时都会执行updateItem检查。如果您的MrBean是ViewScoped而不是SessionScoped,我建议改为使用@PostConstruct
注释。