5

考虑一个简单的 h:outputText 组件:

<h:outputText value="#{myBean.myValue}"/>

如何在页面呈现后延迟加载该值,并在完成此操作时显示自定义“ajax 加载”图标而不是值?

我在我的项目中使用 PrimeFaces 3.5,因此欢迎任何特定于 PF 的实现。

4

3 回答 3

6

建议通过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因为它包含一些长时间运行的计算,但是如果你想完全推迟在你的支持 bean 中outputText首次添加boolean属性的渲染,并将这个属性设置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"/>
于 2013-03-13T16:07:35.017 回答
1

您可以使用BlockUI在加载时有条件地阻止组件。

  1. 定义一个preRenderComponent事件<h:outputText/>

       <h:outputText id="myText">
          <f:event name="preRenderComponent" id="started"/>
       </h:outputText>
    
  2. <p:blockUI/>用事件的id定义一个作为触发器

       <p:blockUI block="myText" trigger="started" />
    

您可以自定义 blockui 以显示图像或其他内容。

提醒一句:我认为您需要这个,因为您在该组件的吸气剂中做了一些繁重的工作。知道 getter 将在该页面的生命周期中被多次调用。所以隐藏操作需要很长时间的事实不会改变事实。更好的设计是在持久范围内预加载和缓存该组件的值,而不是“加载”颤动的戏剧。

于 2013-03-13T20:42:43.897 回答
1

这就是我最终实现它的方式:

<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>

就我个人而言,我对这个实现并不完全满意:

  1. 延迟加载状态存储在服务器端,而不是客户端应该存储的位置
  2. 我必须在我的支持 bean (getUserLoginLocation) 上实现单独的方法来检索该值,并将其显式存储在另一个属性 (lastLoginLocation) 中。在浏览器中渲染页面后,如果有一个惰性调用的 getter 会更干净
  3. 不容易重用 - 取决于支持 bean 'loaded' 标志(在这种情况下为#{empty myBean.lastLoginLocation}),并且需要动作侦听器来实际设置值。任何基于这种方法的复合组件也将依赖于支持 bean 中的特定代码。

欢迎任何有关如何改进此代码的建议!:)

于 2013-03-14T19:16:13.207 回答