使用Primefaces长时间运行服务器作业时的进度条

时间:2014-09-03 07:36:20

标签: jsf jsf-2 primefaces

我想要一个条形图,显示在jsf / Primefaces中使用commandButton启动的长时间运行的服务器作业的进度。

Primefaces的展示展示了如何使用Ajax创建一个根据服务器端某个变量的状态进行更新的pb:http://www.primefaces.org/showcase/ui/misc/progressBar.xhtml

<h3>Ajax ProgressBar</h3>
<p:commandButton value="Start" type="button" onclick="PF('pbAjax').start();PF('startButton2').disable();" widgetVar="startButton2" />
<p:commandButton value="Cancel" actionListener="#{progressBarView.cancel}" oncomplete="PF('pbAjax').cancel();PF('startButton2').enable();" />
<br /><br />
<p:progressBar widgetVar="pbAjax" ajax="true" value="#{progressBarView.progress}" labelTemplate="{value}%" styleClass="animated" global="false">
    <p:ajax event="complete" listener="#{progressBarView.onComplete}" update="growl" oncomplete="startButton2.enable()"/>
</p:progressBar>

我尝试在action上添加commandButton,以便更新进度值:

<p:commandButton value="Start" type="button" onclick="PF('pbAjax').start();
                    PF('startButton2').disable();" widgetVar="startButton2" action="#{computer.compute()}"/>

计算机bean:

@ManagedBean
@SessionScoped
public class Computer {

    long i;

    public Computer() {
    }

    public String compute() throws InterruptedException {
        i = 1;
        while (i < 10) {
            i++;
            Thread.sleep(1000);
        }
        return "welcomePrimefaces.xhtml";
    }
}

ControllerBean:

ManagedBean
@ViewScoped
public class ControllerBean {

@Inject Computer computer;

    public ControllerBean() {
    }

    private Integer progress;


    public Integer getProgress() {
        if (computer.i == 1){
            progress = 30;
        }
        if (computer.i == 2){
            progress = 60;
        }
        if (computer.i == 3){
            progress = 90;
        }
        if (computer.i == 4){
            progress = 100;
        }
        return progress;
    }

    public void setProgress(Integer progress) {
        this.progress = progress;
    }

    public void onComplete() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Completed"));
    }

    public void cancel() {
        progress = null;
    }

}

但永远不会调用compute方法,i永远不会更新。当然这就是这种逻辑(将computer注入controllerbean)这是不正确的。任何指向它的工作表示赞赏!

1 个答案:

答案 0 :(得分:2)

您的代码可能存在两个问题

  1. button类型的按钮不会执行服务器端操作,它仅适用于导航和客户端业务(主要是javascript)。除非你真的想要,否则你不必在你的按钮上设置type属性(默认为type="submit",执行服务器端操作的类型。)

    < / LI>
  2. 根据您的JSF版本,在组合@Inject@ManagedBean类型bean时,您可能无法成功注入Bean。在JSF-2.2之前,CDI(@Inject)和JSF(@ManagedBean等)之间的握手非常错误。注入JSF托管bean的最有效方法是使用@ManagedProperty注释。


  3. 将两者放在一起,你应该:

    <p:commandButton value="Start" onclick="PF('pbAjax').start();
                    PF('startButton2').disable();" widgetVar="startButton2" action="#{computer.compute()}"/>
    

    在你的支持豆

    @ManagedProperty(value="#{computer}")
    Computer computer;
    

    @ManagedProperty注释将使用类名的全小写版本,因为您没有明确指定该托管bean的名称

    相关阅读: