动机:我想在访问时减小页面的大小,所以我认为modalPanels上的延迟渲染会有所帮助。想法是在用户单击显示它的链接时呈现modalPanel。
我想在点击显示它的链接时在rich:modalPanel
上进行延迟渲染。为实现这一目标,我找到了一种方法:
modalPanel
的代码,包含在a4j:outputPanel
<a4j:outputPanel id="a4jPanel">
<rich:modalPanel id="panel" rendered="#{bean.renderPanel}">
<!-- here modalPanel things -->
</rich:modalPanel>
</a4j:outputPanel>
支持bean的代码(会话范围):
public boolean isRenderPanel() {
return renderPanel; //default value is false;
}
public void setRenderPanel(boolean value){
this.renderPanel=value;
}
public setRenderFalse(){
this.setRenderPanel(false);
}
调用它的页面代码:
<a4j:form>
<a4j:jsFunction name="setRenderFalse" action="#{user.setRenderFalse}"/>
<a4j:commandLink value="render and show" oncomplete="Richfaces.showModalPanel('panel');setRenderFalse();" reRender="a4jPanel">
<f:setPropertyActionListener target="#{user.renderPanel}" value="true" />
</a4j:commandLink>
</a4j:form>
问题:
modalPanel需要包含在a4j:outputPanel
内,因为直接重新调整modalPanel不起作用(我从不理解为什么)。
渲染后,需要额外的请求将渲染值设置为false(bean是会话范围的)。否则,如果我们重新加载页面,则不会有任何延迟渲染,因为该值设置为true
。
支持bean必须处理一个属性以保持每个modalPanel的状态,尽管每当单击链接时此属性设置为true
,并且当请求为false
时完了。我试图将rendered
状态保留为JS变量,但它似乎不起作用(只有在页面加载后才会读取它们,而不会再次读取。)
更优雅的方式吗?
答案 0 :(得分:7)
关于你的问题有一个很好的解决方案。所有需要的是一种检测回发和几个xhtmls的方法。
首先,我们需要一个有助于指示回发的bean
public class HelperBean {
public boolean isPostback() {
FacesContext context = FacesContext.getCurrentInstance();
return context.getRenderKit().getResponseStateManager().isPostback(context);
}
}
empty.xhtml - 表示空白内容
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
</ui:composition>
modal.xhtml - 用于包装模态定义
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<rich:modalPanel id="myLazyModal">
<h:outputText value="Modal Content"/>
</rich:modalPanel>
</ui:composition>
lazyModal.xhtml - 用于处理包含上述xhtmls
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<a4j:include id="lazyModal" layout="block"
viewId="#{helperBean.postback ? 'modal.xhtml' : 'empty.xhtml'}"/>
</ui:composition>
最后使用它
<h:form id="frmTest">
<a4j:include id="lazyModalContainer" layout="block" viewId="lazyModal.xhtml"/>
<a4j:commandButton id="btnSubmit" value="Submit" reRender="lazyModalContainer"
oncomplete="Richfaces.showModalPanel('myLazyModal');"/>
</h:form>
现在加载页面时,将包含empty.xhtml,直到btnSubmit
被点击。
关于你提到的问题(1):
使用渲染属性重新渲染组件有点吸引人。当渲染表达式计算为false时,不会将标记发送回客户端。因此,将无渲染组件的id提供给reRender属性将永远不会起作用,因为客户端(DOM)上没有此类ID。
答案 1 :(得分:1)
我认为你应该制作模态面板的单独xhtml(facelet)并使用ui:include而不是链接点击链接,不需要布尔属性。
enter code here : <ui:include src="modalPanel path">, <a4j:commandLink id="abclink" oncomplete="#{rich:component('yourPanelname')}.show()" reRender="yourPanelForm"/>
答案 2 :(得分:1)
另一个解决方案是在JSF组件树中以编程方式设置modalpanel的render属性。因此,您不需要额外的支持bean,它必须处理一个属性以保持每个modalPanel的状态:
Managed Bean:
public void togglePanel(ActionEvent event) {
UIComponent component = event.getComponent();
String forId = (String) component.getAttributes().get("for");
FacesContext currentInstance = FacesContext.getCurrentInstance();
UIComponent findComponent = ComponentFinder.findComponent(currentInstance.getViewRoot(), forId);
findComponent.setRendered(!findComponent.isRendered());
}
查看:
打开面板:
<a4j:commandLink actionListener="#{myBean.togglePanel}" value="Open">
<f:attribute name="for" value="targetPanelId" />
关闭Panel:
<a4j:commandLink id="closePanel" actionListener="#{myBean.togglePanel}" value="someLabel">
<f:attribute name="for" value="targetPanelId" />
模态面板:
<a4j:outputPanel ajaxRendered="true">
<rich:modalPanel id="targetPanelId" width="800" height="500" rendered="false" showWhenRendered="true">