我正在构建一个允许用户管理任务的应用程序。两个用户可以同时访问任务监控屏幕。每个用户都可以查看任务当前是否正在运行,并可以停止或启动它。每当一个用户启动/停止任务时,另一个用户必须在她自己的屏幕上看到任务状态更改。
但是,我构建的代码不起作用。当用户启动任务时,另一个用户的屏幕会尝试立即停止任务。然后开始某种“战争”:第一个用户的屏幕重新激活任务,第二个用户重新启动任务,依此类推。
我怎样才能避免这场战争?
这是我的代码:
taskMonitoring.xhtml
<p:poll
interval="5"
process="sbbActivateTask" />
<h:outputLabel
value="Activate task:" />
<p:selectBooleanButton
id="sbbActivateTask"
value="#{taskBean.state}"
onLabel="YES"
offLabel="NO"
valueChangeListener="#{taskBean.switchTask}"/>
TaskBean.java
@ManagedBean(name = "taskBean")
@ViewScoped
public class TaskBean {
public void setState(boolean b) {
// I deliberately put nothing here ...
}
public boolean getState() {
return TaskManager.getState();
}
public void switchTask() {
TaskManager.switchTask();
}
}
答案 0 :(得分:1)
我猜想当轮询触发并更新<selectBooleanButton>
时,它会看到更改并触发valueChangeListener
,然后将其切换回来,从而竞争条件。我宁愿不在同一个控件中混合使用state和command。
我的建议:与showcase of the component相同的代码。即:
<p:selectBooleanButton
id="sbbActivateTask"
value="#{taskBean.state}"
onLabel="YES"
offLabel="NO"
>
<p:ajax listener="#{taskBean.switchTask}"/>
</p:selectBooleanButton>
这样,只有在用户实际按下按钮时才会触发操作。
要使按钮直观更新,您需要将update
属性添加到poll
:
<p:poll
interval="5"
process="sbbActivateTask"
update="selectBooleanButton" />