1

I have: button on main page and dialog.

A would like to have ViewScope life cycle for managed bean (NewDialog.java), what perform the dialog. In other words: recreate the NewDialog bean while pushing the button, and destroy while closing dialog.

But NewDialog bean has created while loading main page. How to force bean created only when you press a button?

<ui:composition
   <h:form id="mainForm">
      <p:commandButton value="New Dialog"
                  onclick="newDialogVar.show();"/>  
   </h:form>

        <ui:include src="#{viewScopedBean.page}.xhtml" />
    </ui:define>
</ui:composition>

Included page:

    <ui:composition ..
        <f:view >
       <h:form id="formId"
         <p:dialog appendToBody="false"
                  dynamic="true"
                  modal="true"
                  widgetVar="newDialogVar">

              <p:commandButton value="Ok"
                         actionListener="#{newDialog.ok}"/>
      </h:form>
    </p:dialog>
    </f:view>
</ui:composition>

Bean:

@ManagedBean
@ViewScoped
public class NewDialog implements Serializable{

  @PostConstruct
    protected void postConstruct() {
        LOG.info("----------------- PostConstruct -------------------");
    }
}

I use: PrimeFaces 3.5 with Mojarra 2.1.22

Thanks in advance!

P.S. : according research I add:

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

to web.xml.

Olga
  • 3,705
  • 1
  • 20
  • 23

2 Answers2

3

This is expected behavior. The <ui:include> runs during view build time, not during view render time. So even if you conditionally render one of its parents, it will still evaluate its src attribute during building/restoring of the view. In depth background explanation of "view build time" versus "view render time" can be found in this answer: JSTL in JSF2 Facelets... makes sense?

Your concrete functional requirement is unclear, so I can't elaborate the right approach in detail, but fact is, you need to look for an alternate approach if you want to postpone the creation of the bean to display of the dialog. Perhaps you need to split the bean in two ones, one holding the include path and another holding the dialog's data?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the quick reply! About - I agree with you, but I have not idea how to do in an other way. It is necessary to have the dialog over main page. – Olga Jun 06 '13 at 14:10
  • 1
    About functional requirement: yes, I want to postpone the creation of the bean. Reason: at first user should to choose the component into main page, according to this component dialog will be created. Dialog is heavy, and I don't want keep it during all live-cycle of main page. – Olga Jun 06 '13 at 14:15
  • Then split the bean. One which is used during building of the view (which should preferably be request scoped, by the way, unless you're using at least Mojarra 2.1.18, see also the linked JSTL link) and another one which is used during rendering of the view and processing of form submits. In that another one you can just perform and manage the initialization/loading of the data. – BalusC Jun 06 '13 at 14:17
  • Dialog must be initialized, otherwise I get Null pointer from Component into dialog. – Olga Jun 06 '13 at 14:20
0

I have a situacion like you to show a graphic inside dialog, this button call a methot to set src to dialog:

<p:commandButton value="Montos" update=":form2:growl, :form2:displaygraf" oncomplete="montosDialog.show()" actionListener="#{serviciosMB.mostrarGraf}" icon="ui-icon-disk"/> 

this is the dialog (in the same page)

  <p:dialog id="dialog" header="Estado del monto del contrato" widgetVar="montosDialog" resizable="false">  
      <p:panel id="displaygraf">
          <ui:include src="#{serviciosMB.urlGrafMontos}" />  
      </p:panel>
   </p:dialog> 

managedbean serviciosMB:

 public void mostrarGraf() throws Exception {
    try {
        if (this.servicioUtilNew.getContratoUtil().getMontosList().isEmpty()) {
            this.urlGrafMontos ="void.xhtml";
            JsfUtil.addWarnningMessage("El contrato no tiene montos definidos");
        } else {
              this.urlGrafMontos ="grafMontosServicios.xhtml";
        }
    } catch (Exception e) {
        JsfUtil.addErrorMessage(e, "Error: addOrdenProdServArr() " + e.getMessage());

    }
}

this is grafMontosServicios.xhtml

 <h:body>              
    <p:barChart id="stacked1" value="#{grafMontosServiciosMB.categoryModelChartMontos}"   legendPosition="ne" animate="true"
                    title="Estado del monto del contrato" barMargin="20" style="height:300px; width: 500px"/>                                                                      
</h:body>

managed bean where graphic is built

public CartesianChartModel getCategoryModelChartMontos() {
    return categoryModelChartMontos;
}

public void setCategoryModelChartMontos(CartesianChartModel categoryModelChartMontos) {
    this.categoryModelChartMontos = categoryModelChartMontos;
}
/**
 * Creates a new instance of GrafMontosServiciosMB
 */
public GrafMontosServiciosMB() {
}
@PostConstruct
public void crearTablaMontos() {
    try {
        ...           
    } catch (Exception e) {
        JsfUtil.addErrorMessage(e, "Error: createCategoryModel() " + e.getMessage());
    }
}

}

meyquel
  • 2,134
  • 5
  • 23
  • 42