我的目标是动态加载 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/