ленивый рендеринг modalPanel при отображении - PullRequest
7 голосов
/ 07 июля 2010

Мотивация: я хочу уменьшить размер страницы при доступе, поэтому я подумал, что ленивый рендеринг на модалпанелях поможет. Идея состоит в том, чтобы визуализировать modalPanel, когда пользователь нажимает на ссылку, которая его отображает.

Я хочу ленивый рендер на rich:modalPanel при нажатии на ссылку для отображения. Для этого я нашел способ:

Код modalPanel, завернутый в a4j:outputPanel

 <a4j:outputPanel id="a4jPanel">
  <rich:modalPanel id="panel" rendered="#{bean.renderPanel}">
         <!-- here modalPanel things -->
  </rich:modalPanel>
 </a4j:outputPanel>

Код поддерживающего компонента (область действия сеанса):

   public boolean isRenderPanel() {
   return renderPanel;   //default value is false;
   }

    public void setRenderPanel(boolean value){
           this.renderPanel=value;
    }

    public setRenderFalse(){
           this.setRenderPanel(false);
    }

Код страницы, на которой он вызывается:

<a4j:form>
<a4j:jsFunction name="setRenderFalse" action="#{user.setRenderFalse}"/>
<a4j:commandLink value="render and show"  oncomplete="Richfaces.showModalPanel('panel');setRenderFalse();" reRender="a4jPanel">
<f:setPropertyActionListener target="#{user.renderPanel}" value="true" />
</a4j:commandLink>
</a4j:form>

Проблемы:

  • ModalPanel необходимо обернуть в a4j:outputPanel, потому что повторный рендеринг modalPanel не работает (я никогда не понимал, почему).

  • После его рендеринга требуется дополнительный запрос, чтобы установить значение рендеринга равным false (bean-компонент является областью действия сеанса). В противном случае, если мы перезагрузим страницу, не будет никакого отложенного рендеринга, потому что значение было установлено на true.

  • Поддерживающий компонент должен обрабатывать одно свойство, чтобы сохранить состояние для каждого modalPanel, хотя это свойство устанавливается равным true при каждом щелчке ссылки и устанавливается на false, когда запрос завершается. Я пытался сохранить состояние rendered с помощью переменных JS, но, похоже, оно не работает (они просто читаются после загрузки страницы и никогда больше).

Есть более элегантный способ сделать это?

Ответы [ 3 ]

7 голосов
/ 08 августа 2010

Есть хорошее решение по вашему вопросу. Все, что нужно, - это способ обнаружить обратную передачу и пару xhtmls.

Прежде всего нам нужен бин, который поможет с индикацией обратной передачи

public class HelperBean {

    public boolean isPostback() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getRenderKit().getResponseStateManager().isPostback(context);
    }

}

empty.xhtml - для пустого содержимого

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich">

</ui:composition>

modal.xhtml - для переноса модального определения

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich">

    <rich:modalPanel id="myLazyModal">
        <h:outputText value="Modal Content"/>
    </rich:modalPanel>
</ui:composition>

lazyModal.xhtml - для обработки включения вышеупомянутых xhtmls

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich">

    <a4j:include id="lazyModal" layout="block"
        viewId="#{helperBean.postback ? 'modal.xhtml' : 'empty.xhtml'}"/>
</ui:composition>

наконец используйте его

   <h:form id="frmTest">
        <a4j:include id="lazyModalContainer" layout="block" viewId="lazyModal.xhtml"/>
        <a4j:commandButton id="btnSubmit" value="Submit" reRender="lazyModalContainer"
            oncomplete="Richfaces.showModalPanel('myLazyModal');"/>
   </h:form>

Теперь, когда страница загружена, пустой. Xhtml будет включен до тех пор, пока не будет нажата btnSubmit.


Относительно упомянутых вами проблем (1):

Перерисовка компонентов с атрибутом рендеринга немного бросается в глаза. Когда визуализированное выражение оценивается как ложное, разметка не отправляется обратно клиенту. Следовательно, предоставление идентификатора не визуализированного компонента атрибуту reRender никогда не будет работать, поскольку на стороне клиента (DOM) такого идентификатора нет.

1 голос
/ 07 мая 2013

Другое решение состоит в том, чтобы программно установить атрибут рендеринга вашей модальной панели в дереве компонентов JSF. Таким образом, вам не понадобится дополнительный компонент поддержки, который должен обрабатывать одно свойство для сохранения состояния для каждой модальной панели:

Управляемый компонент:

public void togglePanel(ActionEvent event) {
    UIComponent component = event.getComponent();
    String forId = (String) component.getAttributes().get("for");

    FacesContext currentInstance = FacesContext.getCurrentInstance();
    UIComponent findComponent = ComponentFinder.findComponent(currentInstance.getViewRoot(), forId);
    findComponent.setRendered(!findComponent.isRendered());
}

Вид:

Открыть панель:

<a4j:commandLink actionListener="#{myBean.togglePanel}" value="Open">
<f:attribute name="for" value="targetPanelId" />

Закрыть панель:

<a4j:commandLink id="closePanel" actionListener="#{myBean.togglePanel}" value="someLabel">
<f:attribute name="for" value="targetPanelId" />

Модалпанель:

<a4j:outputPanel ajaxRendered="true">
        <rich:modalPanel id="targetPanelId" width="800" height="500" rendered="false" showWhenRendered="true">
1 голос
/ 14 июля 2010

я думаю, что вы должны создать отдельный xhtml (лицевую сторону) модальной панели и использовать ui: include, а затем по ссылке нажмите на ссылку, нет необходимости в логическом свойстве, чем.

enter code here : <ui:include src="modalPanel path">, <a4j:commandLink id="abclink" oncomplete="#{rich:component('yourPanelname')}.show()" reRender="yourPanelForm"/>
...