6 Replies Latest reply on Sep 12, 2011 6:42 AM by Jesper Vrelits

    outputPanel + popupPanel = new ViewScoped bean instance created per each rendering

    Dmitry Shultz Novice

      Hi All,

       

      I'm having hard time trying to use rich:popupPanel inside of a4j:outputPanel, here is the code:

       

      TestBean.java:

       

      @ManagedBean

      @ViewScoped

      public class TestBean {

       

          boolean initiated;

       

          private boolean isVisible;

       

          public void init(){

              if(!initiated){

                  initiated = true;

                  System.out.println("TestBean initiated");

              }

          }

       

          public void setSomething(){

              System.out.println("TestBean changed");

              setVisible(false);

          }

       

          public boolean isVisible() {

              return isVisible;

          }

       

          public void setVisible(boolean visible) {

              isVisible = visible;

          }

      }

       

       

      test.xhtml

       

      <?xml version="1.0" encoding="UTF-8"?>

      <!DOCTYPE html

              PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

       

      <html xmlns="http://www.w3.org/1999/xhtml"

            xmlns:c="http://java.sun.com/jsp/jstl/core"

            xmlns:h="http://java.sun.com/jsf/html"

            xmlns:f="http://java.sun.com/jsf/core"

            xmlns:ui="http://java.sun.com/jsf/facelets"

            xmlns:a4j="http://richfaces.org/a4j"

            xmlns:rich="http://richfaces.org/rich">

       

      <f:view contentType="text/html">

       

          <f:event type="preRenderView" listener="#{testBean.init}"/>

       

          <h:head>

       

          </h:head>

       

          <h:body>

       

              <h:form>

                  <a4j:commandButton action="#{testBean.setVisible(true)}" value="Show Popup" render="testModalPanel"/>

              </h:form>

       

              <a4j:outputPanel id="testModalPanel">

                  <rich:popupPanel id="testModal" modal="true" autosized="false" resizeable="true" width="600" height="400"

                                   show="#{testBean.visible}">

       

                      <h:form>

       

                          <a4j:commandButton id="btnSave" value="#{m_.save}" action="#{testBean.setSomething()}"

                                             execute="@form"

                                             style="margin:5px"

                                             oncomplete="#{rich:component('testModal')}.hide(); return false;"

                                             limitRender="true"/>

                      </h:form>

       

                  </rich:popupPanel>

              </a4j:outputPanel>

       

          </h:body>

       

      </f:view>

      </html>

       

      The problem is that each time the testModalPanel is rerendered (using ajaxRendered="true" or directly form a4j:commandButton by render="testModalPanel") the new instance of TestBean is created.

       

      I don't understand what's going on here. TestBean is ViewScoped, so it should not be recreated for each Ajax request or should it?

       

      If I replace the whole rich:popupPanel by something like this:

       

      <h:outputText value="#{testBean.isVisible()}"/>

       

      it works as expected - only one TestBean instance is created for page.

       

      Spent couple of days with it and totally stuck now, any help or clarification will be usefull.

       

      Thanks,

      Dmitry.