Событие OnShow срабатывает без необходимости при каждой перезагрузке страницы

#java #jsf #primefaces #lazy-loading #lazy-initialization

#java #jsf #первичные #отложенная загрузка #отложенная инициализация

Вопрос:

У меня проблема с созданием меню в моем проекте с использованием Primefaces. На самом деле, это меню даст мне возможность показать несколько небольших диалоговых окон с настройками для рабочей области (нажав на пункты меню). В каждом диалоговом окне должна быть отложенная загрузка данных из базы данных. К сожалению, когда я включаю свои диалоги на страницу (один файл xhtml или пару файлов xhtml с ui:include), при каждой перезагрузке страницы происходит событие OnShow, и это неправильно и вызывает слишком много ненужных запросов к базе данных.

Вот пример:

Часть пользовательского интерфейса

 <h:form id="form1">
    <p:menubar id="mainMenu">
    <p:submenu label="Main menu" icon="ui-icon-document">
        <p:menuitem value="My settings" onclick="mySettingsWv.show()" url="#" />
    </p:submenu>
    </p:menubar>
</h:form>

<p:dialog id="mySettingsDlg" header="My Settings" widgetVar="mySettingsWv" resizable="false"
          closable="true" modal="true" showEffect="fade" hideEffect="explode" dynamic="true"
          closeOnEscape="true" onShow="#{mybean.onShow()}">
        <h:outputLabel value="Settings dialog" />
</p:dialog>
  

Управляемая часть:

 @ManagedBean (name = "mybean")
@ViewScoped
public class MyBean {
   public static Logger log = Logger.getLogger(MyBean.class);

    public void onShow() {
       log.info("Method onShow is being called on each page reloading, but dialog still has not been shown");
     }
}
  

Если я использую действие «onclick» для <p:menuitem> ручного вызова необходимого метода, оно все равно выполняет его при каждой перезагрузке страницы. Также, если я попытаюсь использовать ActionListener, атрибуты действия не сработают. <p:ajax> не может быть присоединено к <p:menuitem> .

Что мне делать в этом случае? Что не так может быть в моем коде?

Комментарии:

1. Вы могли бы обернуть свой диалог внутри div с атрибутом ‘rendered’, чтобы он вообще не отображался в dom, пока вы действительно этого не захотите. и используйте вызов ajax, чтобы показать / скрыть это. Ваша проблема в том, что на странице всегда отображается диалоговое окно, поэтому показ завершен.

Ответ №1:

Взгляните на документацию по p:dialog primefaces (та же проблема с p:menuitem и onclick). Там в документации говорится о onShow :

Обратный вызов на стороне клиента для выполнения при отображении диалогового окна. (выделено мной)

Это означает, что вы можете указать там функцию javascript, но это не работает таким образом, чтобы указать действие на вашем backingbean, которое вызывается каждый раз, когда отображается диалоговое окно. В вашем случае происходит следующее: #{mybean.onShow()} вычисляется только тогда, когда файл проанализирован (т. Е. p:dialog отображается в HTML), а затем туда вставляется значение, возвращаемое методом (т. Е. пустая строка).

Чтобы исправить это, вы должны определить обратный вызов javascript, который выполняет вызов компонента. Вы можете сделать это с помощью p:remoteCommand :

 <p:remoteCommand name="onShow" action="#{mybean.onShow}"
      partialSubmit="true" process="@this"/>
  

А затем укажите этот обратный вызов в качестве onShow атрибута:

 <p:dialog id="mySettingsDlg" ...
      onShow="onShow()">