JSF延迟加载组件值
考虑一个简单的h:outputText组件:JSF延迟加载组件值,jsf,jsf-2,primefaces,Jsf,Jsf 2,Primefaces,考虑一个简单的h:outputText组件: <h:outputText value="#{myBean.myValue}"/> <p:ajaxStatus style="width:16px;height:16px;" id="ajaxStatusPanel"> <f:facet name="start"> <h:graphicImage value="ajaxloading.gif" /> </f:facet
<h:outputText value="#{myBean.myValue}"/>
<p:ajaxStatus style="width:16px;height:16px;" id="ajaxStatusPanel">
<f:facet name="start">
<h:graphicImage value="ajaxloading.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<h:outputText id="myText" value="#{myBean.myValue}"/>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myText"/>
如何在页面呈现后延迟加载该值,并在执行此操作时显示自定义的“ajax加载”图标而不是该值
我在我的项目中使用PrimeFaces 3.5,因此任何特定于PF的实现都是受欢迎的。建议在页面加载后调用
remoteCommand
(通过将autoRun
属性设置为true来完成)并更新outputText
private String myValue;
// getter and setter
public void initMyValue() {
// init myValue
}
在第页上,您应该有用于查看加载图像的ajaxStatus
组件和您的outputText
。还应该有p:remoteCommand
组件:
<h:outputText value="#{myBean.myValue}"/>
<p:ajaxStatus style="width:16px;height:16px;" id="ajaxStatusPanel">
<f:facet name="start">
<h:graphicImage value="ajaxloading.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<h:outputText id="myText" value="#{myBean.myValue}"/>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myText"/>
在页面上,将其重新组织如下:
<h:panelGroup id="myPanel" layout="block">
<h:graphicImage value="ajaxloading.gif" rendered="#{!myBean.loaded}"/>
<h:outputText value="#{myBean.myValue}" rendered="#{myBean.loaded}"/>
</h:panelGroup>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myPanel"/>
在加载组件时,可以使用有条件地阻止组件
,事件id作为触发器
<p:blockUI block="myText" trigger="started" />
一句警告:我想你需要这个,因为你正在做一些繁重的工作,在该组件的吸气剂。知道getter在该页面的生命周期中将被调用多次。因此,隐藏操作需要很长时间的事实不会改变事实。更好的设计是在持久范围内预加载和缓存该组件的值,而不是“加载”throbber的戏剧性 这就是我最终实现它的原因:
<h:panelGroup id="loginLocation">
<p:graphicImage library="assets" name="small-kit-loader.gif" width="16" height="16" rendered="#{empty mybean.lastLoginLocation}"></p:graphicImage>
<h:outputText value="#{myBean.lastLoginLocation}" rendered="#{!empty myBean.lastLoginLocation}"/>
</h:panelGroup>
<p:remoteCommand global="false" actionListener="#{actionBean.getUserLoginLocation(myBean.selectedUser)}" name="refreshLoginLocation" id="rc1" autoRun="true" update="loginLocation" process="@this"></p:remoteCommand>
就我个人而言,我对这一实施并不完全满意:
欢迎对如何改进此代码提出任何建议!:) 看起来它可以工作,但也意味着myText将在页面呈现期间被急切地加载。我怎样才能避免呢?我意识到我可以在backingbean中实现它,但是如果只是懒洋洋地加载它就好了。此外,在本例中,ajaxStatus将是全局的-我只希望显示一个加载状态,而不是专门用于此组件的值。谢谢我编辑了一个答案。我添加了一个可能更适合你需要的部分。是的,经过一点调整后就可以了。尽管如此,对于这样一个简单的任务来说,以上所有这些都是非常麻烦的。难道没有更优雅的解决方案吗?我会写一个组件来做延迟渲染…事实上,按照上面的逻辑,创建将延迟加载其子组件的复合组件并不难。接受你的答案。我还将提供我自己的答案和完整的实施细节。谢谢尝试了,但在向用户显示我的页面之前,会调用preRenderComponent事件侦听器。这是一个模态动态PF对话框-想知道这是否与它有关?另外,我完全理解您关于在持久作用域中缓存值的说法-在本例中,我使用API调用将IP地址解析为位置,并且由于API调用的数量有限,除非用户实际查看数据,否则我宁愿不这样做。@rootkit,现在有了更好的上下文,我可以建议一个更合适的解决方案。在对话框上设置
dynamic=“true”
,以停止在页面加载时加载对话框内容。此外,outputText的rendered
属性可以设置为有条件的,以确保只有在需要时才将元素放入DOM对话框已经是动态的,但我会多次显示它。我希望只有当用户打开对话框时才能查找位置,而且由于查找需要几秒钟的时间,我不想延迟打开对话框…@rootkit然后将文本的rendered
属性设置为将在单击按钮时切换的条件。如果bean是@RequestScoped
,则可以确保在对话框完全渲染后,渲染条件始终重置为false
或任何默认值。发布你的观点的ssce,我可以给代码样本为什么点击按钮?我不希望用户单击任何要加载的值。相反,autoStart=true的p:remoteCommand可以调用切换“渲染”属性的方法。这正是@partlov所建议的。