考虑一个简单的h:outputText组件:
<h:outputText value="#{myBean.myValue}"/>
我怎么能在页面被渲染后延迟加载该值,并显示自定义的"ajax加载"图标而不是值,而这是这样做的?
我在我的项目中使用PrimeFaces 3.5,因此任何特定于pf的实现都将受到欢迎。
建议在页面加载后调用remoteCommand
(通过将autoRun
属性设置为true来完成)并更新您的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"/>
EDIT:我认为你想延迟加载outputText
的值,因为它包含一些长时间运行的计算,但是如果你想完全延迟outputText
的渲染,首先在你的后台bean中添加boolean
属性,并在initMyValue
方法结束时将此属性设置为true
:
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/>
上定义preRenderComponent
事件<h:outputText id="myText"> <f:event name="preRenderComponent" id="started"/> </h:outputText>
-
定义一个带有事件id的
<p:blockUI/>
作为触发器<p:blockUI block="myText" trigger="started" />
您可以自定义块来显示图像或其他内容。
一个警告:我假设你需要这个,因为你在该组件的getter中做了一些繁重的工作。要知道,在该页的生命周期中,getter将被调用几次。因此,隐瞒手术花费很长时间的事实并不能改变事实。更好的设计是在持久作用域中预加载并缓存该组件的值,而不是像"加载"抽动器那样引人注意。
我最终是这样实现的:
<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>
我个人对这个实现不是很满意:
- 延迟加载状态存储在服务器端,而不是应该存储在客户端
- 我必须在我的支持bean (getUserLoginLocation)上实现单独的方法来检索值,并显式地将其存储在另一个属性(lastLoginLocation)中。如果在浏览器 中渲染页面后使用一个getter惰性调用,会简洁得多。
- 不容易重用-取决于后台bean 'loaded'标志(#{empty myBean。lastLoginLocation}),并且需要操作监听器来实际设置该值。任何基于这种方法的组合组件也将依赖于后台bean中的特定代码。
欢迎任何关于如何改进此代码的建议!:)