我想要一个条形图,显示在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
)这是不正确的。任何指向它的工作表示赞赏!
答案 0 :(得分:2)
您的代码可能存在两个问题
button
类型的按钮不会执行服务器端操作,它仅适用于导航和客户端业务(主要是javascript)。除非你真的想要,否则你不必在你的按钮上设置type
属性(默认为type="submit"
,执行服务器端操作的类型。)
根据您的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()}"/>
在你的支持豆
中@ManagedProperty(value="#{computer}")
Computer computer;
@ManagedProperty
注释将使用类名的全小写版本,因为您没有明确指定该托管bean的名称
相关阅读: