JSF 2.0:延迟渲染(复合)组件的内容,直到AJAX调用重新渲染它
我的目标是动态加载JSF 2.0中组件的内容。用例是这样的:用户点击一些按钮,通过AJAX打开一些带有大量内容的模式面板。由于它的沉重感,我想延迟加载直到/如果用户实际需要它。如果用户关闭此面板,它实际上并未从DOM中删除,只是淡出。如果用户再次点击初始化按钮,则显示先前加载的面板。JSF 2.0:延迟渲染(复合)组件的内容,直到AJAX调用重新渲染它
我知道我可以防止使用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 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只是将目标包装成一个漂亮的窗口面板。在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的,虽然我不知道我会怎么做反正这与它:)
好吧我挖自己的部分解决方案作为一个接受的时间之中。如果有人有更好的建议,我会很乐意改变选择:) – 2010-09-28 12:41:14