如何显示 f:viewAction 的等待指示器?

Posted

技术标签:

【中文标题】如何显示 f:viewAction 的等待指示器?【英文标题】:How to display a wait indicator for f:viewAction? 【发布时间】:2019-10-23 00:18:53 【问题描述】:

我有一个加载对象属性的 JSF 页面(其 id 在 URL 中传递)。加载可能会持续更多秒,所以我想显示等待/忙碌指示符或“正在加载...”消息。

这是使用“viewAction”完成的

<f:metadata>
    <f:viewAction action="#myBean.loadParams" />
</f:metadata>

有没有简单的方法来实现这个目标?我正在使用 Primefaces。

【问题讨论】:

我正在使用 Primefaces 【参考方案1】:

我也想提出这个简单的方法:

一个“登陆”页面(我们第一次导航的页面),带有一个等待指示器和一个带有从 URL 读取参数“param”并将其保存在 bean 中的事件的 autoRun remoteCommand。 remoteCommand 重定向到另一个页面(执行长时间运行的方法 loadParams) 这样,等待指示器会一直显示,直到准备好显示第二页。

你有什么弱点吗?

这里是登陆页面:

<!DOCTYPE html>
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
<h:head>
...
</h:head>
<f:metadata>
     <f:event type="postAddToView" listener="#notHeavyBean.readProperty" />
     <f:viewParam name="param"/>
</f:metadata>
<h:body>
  <p:outputPanel layout="block">
      <i class="fa fa-circle-o-notch fa-spin layout-ajax-loader-icon" aria-hidden="true" style="font-size: 40px;position: relative;top: 50%;left: 50%;"></i>
  </p:outputPanel>


<h:form>
    <p:remoteCommand action="#notHeavyBean.redirect" autoRun="true"/>
</h:form>


</h:body>

【讨论】:

【参考方案2】:

PrimeFaces 已经为此准备了一个组件:&lt;p:outputPanel deferred="true"&gt;。您只需要确保#heavyBean&lt;p:outputPanel&gt; 和不在别处。

...
#notHeavyBean.property
...

<p:outputPanel deferred="true">
    ...
    #heavyBean.property
    ...
</p:outputPanel>

...
#anotherNotHeavyBean.property
...

然后您可以在其@PostConstruct 方法中完成繁重的工作。在@PostConstruct 中完成您最初在&lt;f:viewAction&gt; 中所做的工作。

@Named
@ViewScoped
public class HeavyBean implements Serializable 

    @PostConstruct
    public void init() 
        // Heavy job here.
    

    // ...

如果您需要访问其他 bean 的属性,只需 @InjectHeavyBean 中的那些 bean。例如。如果您需要 ID 视图参数:

<f:viewParam name="id" value="#notHeavyBean.id" />

@Inject
private NotHeavyBean notHeavyBean; // Also @ViewScoped.

@PostConstruct
public void init() 
    Long id = notHeavyBean.getId();
    // Heavy job here.

&lt;p:outputPanel&gt; 已经带有动画 gif。您可以通过 CSS 轻松customize。

.ui-outputpanel-loading 
    background-image: url("another.gif");

【讨论】:

请注意,GIF 可能不是加载器图像的最佳选择。见How to remove borders from loading gif on a dark background? 哇。多谢!我已经尝试过了:唯一的问题是该页面是复杂视图的“入口点”,使用 jstl 标签构建(我无法删除),并且这些标签会导致您预期的问题。我尝试使用 autorun="true" 在延迟窗格中添加远程命令并更新组件。以这种方式它似乎可以工作,但我不确定它是否是一个好的解决方案(性能似乎变得更糟)。

以上是关于如何显示 f:viewAction 的等待指示器?的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 f:viewAction / preRenderView 与 PostConstruct?

根据 f:viewParam 有条件地调用 f:viewAction

f:viewAction 被忽略,当 commandButton 导航到页面时

在使用 p:commandButton 导航时调用 f:viewAction 中的操作

如何在同一个块中等待多个块事件

自动显示等待光标以指示正在进行长时间操作