【发布时间】:2013-03-01 15:44:39
【问题描述】:
考虑一个简单的 h:outputText 组件:
<h:outputText value="#{myBean.myValue}"/>
如何在页面呈现后延迟加载该值,并在完成时显示自定义“ajax 加载”图标而不是值?
我在我的项目中使用 PrimeFaces 3.5,因此欢迎任何特定于 PF 的实现。
【问题讨论】:
标签: jsf jsf-2 primefaces
考虑一个简单的 h:outputText 组件:
<h:outputText value="#{myBean.myValue}"/>
如何在页面呈现后延迟加载该值,并在完成时显示自定义“ajax 加载”图标而不是值?
我在我的项目中使用 PrimeFaces 3.5,因此欢迎任何特定于 PF 的实现。
【问题讨论】:
标签: jsf jsf-2 primefaces
建议在页面加载后调用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"/>
编辑:我想你想延迟加载 outputText 的值,因为它包含一些长时间运行的计算,但如果你想完全推迟 outputText 的渲染,首先添加 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"/>
【讨论】:
这就是我最终实现它的方式:
<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>
我个人对这个实现并不完全满意:
欢迎任何有关如何改进此代码的建议! :)
【讨论】:
您可以使用BlockUI 在加载时有条件地阻止组件。
在<h:outputText/> 上定义preRenderComponent 事件
<h:outputText id="myText">
<f:event name="preRenderComponent" id="started"/>
</h:outputText>
定义一个<p:blockUI/>,事件的id作为触发器
<p:blockUI block="myText" trigger="started" />
您可以自定义 blockui 以显示图像或其他内容。
请注意:我认为您需要这个,因为您在该组件的吸气剂中做了一些繁重的工作。知道 getter 将在该页面的生命周期中被多次调用。所以隐藏操作需要很长时间的事实不会改变事实。更好的设计是在持久范围内预加载和缓存该组件的值,而不是“加载”颤动的戏剧。
【讨论】:
dynamic="true" 以停止在页面加载时加载对话框的内容。此外,outputText 的rendered 属性可以设置为有条件的,以确保元素仅在需要时放入 DOM 中
rendered 属性设置为将在按钮单击时切换的条件。如果您的 bean 是 @RequestScoped,那么您可以确保在对话框完全渲染后立即将渲染条件重置为 false 或任何默认值。发表您的观点,我可以提供代码示例