【问题标题】:Composite component causes unique ID error when binding to view scoped bean复合组件在绑定到视图范围 bean 时导致唯一 ID 错误
【发布时间】:2015-12-02 16:40:11
【问题描述】:

我们正在将 JSF 2.1 应用程序从 JBoss AS 7.2 迁移到 Wildfly,进而迁移到 JSF 2.2。我们遇到的问题如下:我们有一个组合组件,它包含在@ViewScoped bean 中。组件必须通过多个请求来保留其值,因此 Request Scoped bean 不是解决方案。

我们得到的例外是一个多组件 ID。请求后JSF开始第二次渲染组件,失败了。

我为此做了一个简单的演示:

MyViewBean.java

@ViewScoped
@Named
public class MyViewBean implements Serializable {

    private Component component;

    public Component getComponent() {
        return component;
    }

    public void setComponent(Component component) {
        this.component = component;
    }

    public String increment(){
        component.setCounter(component.getCounter()+1);
        return "";
    }
}

Component.java

@FacesComponent(value = "composite")
public class Component extends UINamingContainer {
    private Integer counter = 0;

    public Integer getCounter() {
        return counter;
    }

    public void setCounter(Integer counter) {
        this.counter = counter;
    }


}

compositeTest.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    template="/WEB-INF/templates/default.xhtml"
    xmlns:pelda="http://xmlns.jcp.org/jsf/composite/component">
    <ui:define name="content">
        <h1>Composite component Test!</h1>
        <h:form>
                <pelda:composite binding="#{myViewBean.component}" />
                <h:commandButton action="#{myViewBean.increment()}" value="Push me!"/>
        </h:form>

    </ui:define>
</ui:composition>

composite.xhtml

<cc:interface componentType="composite">
</cc:interface>
<cc:implementation> 
    <h:outputText id="id_hello" value="Helloka" />
    <h:outputText id="id_counter" value="#{cc.counter}" />
</cc:implementation> 
</html>

如何实现计数器可以递增(使用 @RequestScoped bean 重置)并且不会因 idUniqueness 错误而失败?我们正在使用 Mojarra 2.2.8(wildfly 中的默认值),也尝试使用 Mojarra 2.2.12(撰写本文时的最新版本)。

提前致谢!

【问题讨论】:

    标签: jsf jsf-2 binding composite-component


    【解决方案1】:

    UIComponent 实例本质上是请求范围的。您应该切勿引用超出请求范围的 UIComponent 实例。请仔细阅读 How does the 'binding' attribute work in JSF? When and how should it be used? 以获得详细说明。

    您只想通过继承的getStateHelper() 方法将其状态保存为JSF 状态。这基本上充当视图范围。

    @FacesComponent(value = "composite")
    public class Component extends UINamingContainer {
    
        public Integer getCounter() {
            return (Integer) getStateHelper().eval("counter", 0);
        }
    
        public void setCounter(Integer counter) {
            getStateHelper().put("counter", counter);
        }
        
    }
    

    别忘了去掉视图中的binding属性。

    另见:

    【讨论】:

      猜你喜欢
      • 2012-12-23
      • 2017-05-08
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      相关资源
      最近更新 更多