JSF 2.0: задерживать рендеринг (составной) содержимого компонента до тех пор, пока AJAX-вызов не сделает его - PullRequest
1 голос
/ 18 августа 2010

Моя цель - динамически загружать содержимое компонента в JSF 2.0.Вариант использования таков: пользователь нажимает какую-то кнопку, которая открывает модальную панель с большим объемом содержимого через AJAX.Из-за его «тяжести» я хочу отложить его загрузку до тех пор, пока / или пользователю это не понадобится.Если пользователь закрывает эту панель, она фактически не удаляется из DOM, а просто исчезает.Если пользователь снова нажимает кнопку инициализации, отображается ранее загруженная панель.

Я знаю, что могу предотвратить рендеринг содержимого, используя rendered="#{cc.attrs.visibilityState == 'hidden'}", и что я могу повторно визуализировать компонент с помощью вызова JSF AJAX.Тем не менее, как я могу настроить атрибуты составного компонента на лету так, чтобы второй раз вокруг компонента фактически отображался?

1) Я знаю, что могу сделать:

<h:outputLink>Foo
    <f:ajax event="click" render="theComponentIWantToUpdate" listener="#{someBean.someMethod()}" />
</h:outputLink>

А затем программно настроить атрибуты theComponentIWantToUpdate (чтобы изменить значение #{cc.attrs.visibilityState}) так, чтобы он фактически отображался с полным содержимым.Но как на самом деле это сделать?

2) Кроме того, проблема в том, что я не хочу обновлять (перерисовывать) theComponentIWantToUpdate при каждом нажатии кнопки, только в первый раз (см.бизнес-кейс).Как я могу установить оценку для <f:ajax /> вызова для этого?У него есть атрибут disabled, но он только указывает, нужно ли на самом деле отображать обработчик AJAX (не обрабатывается при каждом нажатии ссылки).

3) Кроме того, я, вероятно, хочу сделать несколько пользовательскихСначала javascript при нажатии на ссылку, и только выполнить запрос AJAX через javascript, используя jsf.ajax.request().Однако эта функция не поддерживает предоставление атрибута listener, поэтому я не знаю, как выполнить метод вспомогательного компонента с необработанным вызовом javascript jsf.ajax.request()?На самом деле есть похожий вопрос без подходящих ответов (см. JSF 2.0 AJAX: jsf.ajax.request для вызова метода, а не только для повторного отображения области страницы ).

1 Ответ

1 голос
/ 19 августа 2010

Частичное решение:

Вот моя ссылка, которая отправляет AJAX-запрос (внутри составного компонента):

<h:form>
    <h:outputLink styleClass="modlet-icon">
        <f:ajax event="click" render=":#{cc.clientId}:modalWindow:root" listener="#{modalWindowBean.enableContentRendering(cc.clientId, 'modalWindow')}" />
    </h:outputLink>
</h:form>

Слушатель вызывает этот метод:

public class ModalWindowBean {
    ...

    public void enableContentRendering(String clientId, String windowId) {
        UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId + ":" + windowId);
        component.getAttributes().put("contentRenderingEnabled", true);
    }
}

Вот моя цель для визуализации:

<modalWindow:modalWindow id="modalWindow">
    <quickMenu:quickMenuOverlay id="quickMenuOverlay" />
</modalWindow:modalWindow>

ModalWindow просто оборачивает цель в симпатичную оконную панель. Внутри ModalWindow:

<composite:implementation>
    <h:outputScript library="component/modalWindow" name="modalWindow.js" target="head" />
    <h:outputStylesheet library="component/modalWindow" name="ModalWindow.css" />

    <h:panelGroup id="root" layout="block" styleClass="modalWindow hide">
        <ui:fragment rendered="#{cc.attrs.contentRenderingEnabled}">
            ...all the wrapping elements with <composite:insertChildren /> within it
            <script type="text/javascript">
                // Fade it in
                var win = ModalWindow.getInstance('#{cc.clientId}');  // this gets the instance, available everywhere
                win.position(#{cc.attrs.left}, #{cc.attrs.top});
                win.resize(#{cc.attrs.width}, #{cc.attrs.height});
                win.fadeIn();
            </script>
        </ui:fragment>
    </h:panelGroup>

    <ui:fragment rendered="#{!cc.attrs.contentRenderingEnabled}">
        <script type="text/javascript">
            // Initialize modalWindow when it is rendered for the first time
            var win = new ModalWindow('#{cc.clientId}');  // will be publicly available through ModalWindow static methods
        </script>
    </ui:fragment>

</composite:implementation>

Проблема? AJAX-запрос отправляется каждый раз, когда пользователь нажимает кнопку (таким образом, окно перезагружается и исчезает каждый раз) Мне нужно иметь возможность контролировать, когда / действительно ли отправляется AJAX-запрос.

Все эти вещи заставляют меня скучать по Apache Wicket, хотя я все равно не уверен, как бы я это сделал :)

...