JSF @ViewScope, PrimeFaces ‹p:dialog и ‹ui:include

У меня есть: кнопка на главной странице и диалог.

A хотел бы иметь жизненный цикл ViewScope для управляемого компонента (NewDialog.java), который выполняет диалог. Другими словами: воссоздайте bean-компонент NewDialog при нажатии кнопки и уничтожьте при закрытии диалогового окна.

Но bean-компонент NewDialog был создан при загрузке главной страницы. Как заставить bean создаваться только при нажатии кнопки?

<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>

Включенная страница:

    <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>

Бин:

@ManagedBean
@ViewScoped
public class NewDialog implements Serializable{

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

Я использую: PrimeFaces 3.5 с Mojarra 2.1.22

Заранее спасибо!

P.S. : согласно исследованиям добавляю:

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

в веб.xml.


person Olga    schedule 06.06.2013    source источник


Ответы (2)


Это ожидаемое поведение. <ui:include> запускается во время построения представления, а не во время рендеринга представления. Таким образом, даже если вы условно отобразите один из его родителей, он все равно будет оценивать свой атрибут src во время построения/восстановления представления. В этом ответе можно найти подробное справочное объяснение «времени сборки просмотра» по сравнению с «временем рендеринга просмотра»: sense/3343681#3343681">JSTL в JSF2 Facelets... имеет смысл?

Ваше конкретное функциональное требование неясно, поэтому я не могу подробно описать правильный подход, но факт в том, что вам нужно искать альтернативный подход, если вы хотите отложить создание компонента для отображения диалога. Возможно, вам нужно разделить bean-компонент на два, один из которых содержит путь включения, а другой содержит данные диалога?

person BalusC    schedule 06.06.2013
comment
Спасибо за быстрый ответ! Насчет ‹ui:include› - я с вами согласен, но как по-другому не представляю. Необходимо иметь диалог над главной страницей. - person Olga; 06.06.2013
comment
О функциональном требовании: да, я хочу отложить создание бина. Причина: сначала пользователь должен выбрать компонент на главную страницу, в соответствии с этим компонентом будет создан диалог. Диалог тяжелый, и я не хочу держать его на протяжении всего жизненного цикла главной страницы. - person Olga; 06.06.2013
comment
Затем разделите фасоль. Один используется во время построения представления (кстати, желательно, чтобы область его действия была ограничена запросом, если вы не используете по крайней мере Mojarra 2.1.18, см. также связанную ссылку JSTL), а другой используется во время рендеринга просмотр и обработка отправленных форм. В этом другом вы можете просто выполнять и управлять инициализацией/загрузкой данных. - person BalusC; 06.06.2013
comment
Диалог должен быть инициализирован, иначе я получу нулевой указатель из компонента в диалог. - person Olga; 06.06.2013

У меня есть ситуация, как у вас, чтобы показать графику внутри диалога, эта кнопка вызывает метод, чтобы установить src в диалог:

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

это диалог (на той же странице)

  <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> 

управляемые bean-сервисыMB:

 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());

    }
}

это 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>

управляемый компонент, в котором строится графика

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());
    }
}

}

person meyquel    schedule 07.06.2013