考虑一个简单的H:outputText组件:JSF懒加载组件值
<h:outputText value="#{myBean.myValue}"/>
我怎么能延迟加载该页面后,价值已经呈现,并且代替值,同时显示自定义“AJAX加载”图标这是正在完成?
我在我的项目中使用PrimeFaces 3.5,所以任何PF特定的实现将受到欢迎。
考虑一个简单的H:outputText组件:JSF懒加载组件值
<h:outputText value="#{myBean.myValue}"/>
我怎么能延迟加载该页面后,价值已经呈现,并且代替值,同时显示自定义“AJAX加载”图标这是正在完成?
我在我的项目中使用PrimeFaces 3.5,所以任何PF特定的实现将受到欢迎。
建议在页面加载后(通过将autoRun
属性设置为true)调用remoteCommand
并更新outputText
来完成此操作。
private String myValue;
// getter and setter
public void initMyValue() {
// init myValue
}
在页面上,你应该有ajaxStatus
组件用于查看加载图像,和你的outputText
。还应该有p:remoteCommand
组件:
<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"/>
编辑:我应该要的outputText
延迟加载的价值,因为它包含了一些长时间运行的计算,但如果你想的outputText
完全deffer呈现先加boolean
在你的后台bean的属性,将此属性设置为true
在initMyValue
方法的末尾:
private boolean loaded;
// getter and setter
public void initMyValue() {
// init myValue
loaded = true;
}
在页面上重新组织如下:
<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"/>
您可以使用BlockUI在加载组件时有条件地阻止该组件。
定义在<h:outputText/>
<h:outputText id="myText">
<f:event name="preRenderComponent" id="started"/>
</h:outputText>
一个preRenderComponent
事件定义<p:blockUI/>
与事件的ID作为触发
<p:blockUI block="myText" trigger="started" />
您可以自定义blockui到显示图像或其他。
谨慎的一句话:我认为你需要这个,因为你在这个组件的getter中做了一些繁重的工作。知道getter将在该页面的生命周期中多次调用。因此隐瞒手术花费很长时间的事实不会改变事实。一个更好的设计将是在一个持久的范围内预加载和缓存该组件的值,而不是“加载”跳动者的表演。
尝试过,但在我的页面显示给用户之前调用preRenderComponent事件侦听器。这是一个模态动态的PF对话框 - 想知道这与它有什么关系?此外,我完全理解你在缓存持久范围中的值时所说的话 - 在这种情况下,我有API调用来将IP地址解析为位置,并且由于API调用的数量有限,我宁愿不这样做,除非用户真正查看数据。 – rootkit 2013-03-14 14:52:18
@rootkit,现在有更好的上下文,我可以建议一个更合适的解决方案。在对话框中设置'dynamic =“true”'来阻止加载页面时加载对话框的内容。此外,可以使outputText的'rendered'属性有条件,以确保该元素仅在需要时才放入DOM中 – kolossus 2013-03-14 15:11:57
该对话框已经是动态的,但我多次显示它。我只想在用户打开对话框时查找位置,并且由于查找需要好几秒钟,我不想延迟打开对话框...... – rootkit 2013-03-14 16:14:22
这是我怎么会实现它:
<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将在页面呈现期间急切加载。我怎样才能避免这种情况?我意识到我可以在后台bean中做到这一点,但只要延迟加载就好了。此外,在这种情况下,ajaxStatus将是全局的 - 我只想显示一个加载状态来代替专门为此组件设置的值。谢谢! – rootkit 2013-03-13 16:28:05
我编辑了一个答案。我添加了可能更适合您需求的部分。 – partlov 2013-03-14 07:48:24
是的,这经过一些调整后才起作用。尽管如此,对于这样一个简单的任务来说,上述所有方面都是太麻烦了。没有更优雅的解决方案吗?我会写一个组件来做懒惰的渲染...... – rootkit 2013-03-14 16:27:14