JSF 2.0:为什么我的ViewScope Bean重新创建,即使仍然在同一个View [英] JSF 2.0: Why my ViewScope Beans is re-created even though still on same View

查看:150
本文介绍了JSF 2.0:为什么我的ViewScope Bean重新创建,即使仍然在同一个View的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 < ui:composition xmlns:ui =http ://java.sun.com/jsf/facelets
template =./../ template / CustomerTemplate.xhtml
xmlns:h =http://java.sun.com/ jsf / html
xmlns:f =http://java.sun.com/jsf/core
xmlns:p =http://primefaces.prime.com.tr/ui >

< ui:define name =formContent>
< h:form>
< p:dataGrid var =itemvalue =#{mrBean.items}columns =3>
< p:column>
< p:panel header =#{item.name}>
< h:panelGrid columns =1style =width:100%>
...
< h:commandButton value =添加到购物车actionListener =#{cartBean.addItem(item.id)}/>
...
< / h:panelGrid>
< / p:panel>
< / p:column>
< / p:dataGrid>
< / h:form>
< / ui:define>

< / ui:composition>

CustomerTemplate.xhtml是:

 < html xmlns =http://www.w3.org/1999/xhtml
xmlns:ui =http://java.sun.com/jsf/
xmlns:h =http://java.sun.com/jsf/html
xmlns:p =http://primefaces.prime.com.tr/ui>
< h:head>
< meta http-equiv =Content-Typecontent =text / html; charset = UTF-8/>
... // import css,js files
< / h:head>

< h:body>
... //页面上的其他内容
< div class =grid_9 content>
< ui:insert name =contentTitle>< / ui:insert>
< ui:insert name =formContent>< / ui:insert>
< / div>
...
< / h:body>
< / html>

这是我的ManagedBean:

  @ManagedBean 
@ViewScoped
public class MrBean {
...
private List< ItemState>项目;
...

@PostConstruct
public void prepareItemList(){
...
Map< String,String> params = FacesContext.getCurrentInstance()。getExternalContext()。getRequestParameterMap();
partnerID = Long.parseLong(params.get(partnerID));
...
}
}

正如你所见我的MrBean是一个ViewScoped ManagedBean。我预计@PostContruct函数只会在页面被渲染时被调用一次。但是,当我点击添加到购物车按钮时,我遇到了空值异常,行 Long.parseLong(params.get(partnerID ))即使我仍然在同一个视图。



如果有人可以给我一个关于如何解决这个问题。



更新:我设法通过包装 commandButton ajax 标签之内,如下所示:

  ... 
< f:ajax listener =#{cartManagedBean.addItem(item.id)}>
< h:commandButton value =添加到购物车/>
< / f:ajax>
....


解决方案

很多可能的原因,最终归结为鸡蛋问题,如 JSF问题1492中所述。您正在使用< h:someHtmlComponent binding =...> 将UI组件绑定到视图范围的托管bean属性,或者您绑定一个标签处理程序,如< c:if test =...> < ui:include src =... > 等到视图范围的托管bean属性。



这是在JSF 2.2中进行修复的。在此之前,最好的办法是寻找替代方法,或将上下文参数 javax.faces.PARTIAL_STATE_SAVING 设置为 false



另请参见:




In my .xhtml page, I have the following form:

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
            template="./../template/CustomerTemplate.xhtml"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:p="http://primefaces.prime.com.tr/ui">

    <ui:define name="formContent">
        <h:form> 
            <p:dataGrid var="item" value="#{mrBean.items}" columns="3">
                <p:column>
                    <p:panel header="#{item.name}">
                        <h:panelGrid columns="1" style="width:100%">
                            ...
                            <h:commandButton value="Add To Cart" actionListener="#{cartBean.addItem(item.id)}" />
                            ...
                        </h:panelGrid>
                    </p:panel>
                </p:column>
            </p:dataGrid> 
        </h:form> 
    </ui:define>

</ui:composition>

The CustomerTemplate.xhtml is:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.prime.com.tr/ui">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        ... // import css, js files
    </h:head>

    <h:body>
        ... // Other things on the page
        <div class="grid_9 content">
            <ui:insert name="contentTitle"></ui:insert>
            <ui:insert name="formContent"></ui:insert>
        </div>
        ...
    </h:body>
</html>

And this is my ManagedBean:

@ManagedBean
@ViewScoped
public class MrBean {
    ...
    private List<ItemState> items;
    ...

    @PostConstruct
    public void prepareItemList() {
        ...
        Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
            partnerID = Long.parseLong(params.get("partnerID"));
        ...
    }
}

As you can see, my MrBean is a ViewScoped ManagedBean. I expected that the @PostContruct function will only be called once when the page is 1st rendered. However, when I click the Add To Cart button, I ran into the null exception at the line Long.parseLong(params.get("partnerID")) even though I am still on the same View.

I'd be very grateful if someone could give me an advice on how to tackle this problem.

UPDATE: I managed to get the function working by wrapping the commandButton inside an ajax tag like following:

...
<f:ajax listener="#{cartManagedBean.addItem(item.id)}">
    <h:commandButton value="Add To Cart" /> 
</f:ajax>
....

解决方案

There are a lot of possible reasons for this which all ultimately boils down to the chicken-egg issue as described in JSF issue 1492. You are using <h:someHtmlComponent binding="..."> to bind an UI component to a view scoped managed bean property, or you are binding an attribute of a tag handler like <c:if test="...">, <ui:include src="...">, etc to a view scoped managed bean property.

This is scheduled to be fixed in JSF 2.2. Until then, your best bet is to look for alternative approaches or to set the context parameter javax.faces.PARTIAL_STATE_SAVING to false.

See also:

这篇关于JSF 2.0:为什么我的ViewScope Bean重新创建,即使仍然在同一个View的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆