1

在我的应用程序中,我有以下 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在视图渲染后调用了该方法。

如果您能给我一个建议,我将不胜感激。

最好的祝福,

4

2 回答 2

3

如果在之后#{itemBean}的视图中第一次被引用,就会发生这种情况。例如 #{mrBean.item}

#{mrBean.item}
...
#{itemBean}

当 EL 表达式第一次引用它并且它还不存在于作用域中时,托管 bean 是第一次构造的。在一个 GET 请求中,托管 bean 实例没有被 taghandler 属性或 a 引用f:event,那么它只会在渲染响应期间被构造。

如果重新排列它们以便在被引用之前#{itemBean}总是被引用(并因此被构造)是不可能的,那么最好改为使用a 。 #{mrBean.item}@PostConstruct#{itemBean}<f:event type="preRenderView">

<f:event type="preRenderView" listener="#{itemBean.init}" />
于 2012-07-25T18:21:33.730 回答
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注释。

于 2012-07-25T17:47:49.453 回答