繁体   English   中英

JSF 2.0:延迟呈现(复合)组件的内容,直到AJAX调用重新呈现它为止

[英]JSF 2.0: Delay rendering (composite) component's contents until AJAX-call re-renders it

我的目标是在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,并且仅使用jsf.ajax.request()通过javascript执行AJAX请求。 但是,该函数不支持提供listener属性,因此我不如何通过原始javascript jsf.ajax.request()调用执行后备bean方法? 实际上,还有一个类似的问题,没有合适的答案(请参阅JSF 2.0 AJAX:调用jsf.ajax.request方法不仅要重新呈现页面区域 )。

部分解决方案:

这是发送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,尽管我不确定我将如何使用它:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM