【问题标题】:progress bar while long running server job with Primefaces使用 Primefaces 长时间运行服务器作业时的进度条
【发布时间】:2014-09-03 07:36:19
【问题描述】:

我想要一个显示在 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>

我尝试在commandButton 上添加一个action,这应该可以更新进度值:

<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)。任何让它工作的指针都值得赞赏!

【问题讨论】:

    标签: jsf jsf-2 primefaces


    【解决方案1】:

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

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

    2. 根据您的 JSF 版本,在组合 @Inject@ManagedBean 类型的 bean 时,您可能不会成功进行 bean 注入。在 JSF-2.2 之前,CDI (@Inject) 和 JSF(@ManagedBean 等) 之间的握手非常有问题。注入 JSF 管理的 bean 最有效的方法是使用 @ManagedProperty 注释。


    把两者放在一起,你应该有:

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

    在你的支持 bean 中

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

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

    相关阅读:

    【讨论】:

    • 两个建议都准确。非常感谢。
    猜你喜欢
    • 2014-06-09
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2014-03-27
    • 2015-02-14
    • 1970-01-01
    相关资源
    最近更新 更多