JSF延迟加载组件值

时间:2013-03-13 15:41:42

标签: jsf jsf-2 primefaces

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

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

如何在呈现页面后延迟加载该值,并显示自定义&#39; ajax loading&#39;这是完成后的图标而不是值?

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

3 个答案:

答案 0 :(得分: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的值,因为它包含一些长时间运行的计算,但是如果您想完全取消outputText的渲染在您的支持bean中添加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"/>

答案 1 :(得分:1)

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

  1. preRenderComponent

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

       <p:blockUI block="myText" trigger="started" />
    
  3. 您可以自定义blockui以显示图像或其他任何内容。

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

答案 2 :(得分: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中的特定代码。
  4. 欢迎任何有关如何改进此代码的建议! :)