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

标签 java ajax components jsf-2

我的目标是动态加载 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 执行支持 bean 方法 jsf.ajax.request()称呼?实际上有一个类似的问题没有合适的答案(参见JSF 2.0 AJAX: jsf.ajax.request to call method not only rerender an area of page)。

最佳答案

部分解决方案:

这是我发送 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 只是将目标包装到一个漂亮的窗口面板中。在模态窗口内:

<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,尽管我不确定如何用它来做到这一点:)

关于java - JSF 2.0 : Delay rendering (composite) component's contents until AJAX-call re-renders it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3510916/

相关文章:

php - mysql查询从数据库获取数据并使用php以堆积条形图的形式显示

javascript - Mithril.js 具有多个 GET 请求

delphi - Delphi 的条形码生成库

java - 在 playframework 中验证卡到期日期

java - 如何解决 JSR-303 自定义 validator 中的依赖关系

java - git-push 命令失败

c# - 模型与非顺序索引的 JSON 数组/对象绑定(bind)

delphi - 如何从命令行安装Delphi组件包?

javascript - 在 React 中单击组件时将类添加到 sibling

java - 在 Activity 之外注入(inject)时如何使用 Dagger2 排列组件?