如何通过按钮点击事件停止所有p:poll组件?附多图表场景示例
如何停止所有PrimeFaces Poll组件的点击事件处理方案
针对你提到的场景——拥有多个不同刷新间隔的p:poll绑定图表,需要在点击按钮时停止所有轮询操作,这里提供两种实用的实现方式:
方法一:统一样式类+前端JS遍历控制
这种方式无需额外维护后端变量,纯前端就能快速实现:
- 修改Poll组件定义:给所有
p:poll添加一个统一的样式类(比如chart-poll),保留原有配置:
<c:forEach var="chart" items="#{bean.charts}"> <p:poll interval="#{chart.timeRefresh}" listener="#{bean.updateChart(chart)}" styleClass="chart-poll" /> <div>..draw one-by-one chart here.</div> </c:forEach>
- 调整按钮事件逻辑:在按钮的
onsuccess(或onclick,根据你的触发时机需求)中调用自定义JS函数,同时保留原有弹窗逻辑:
<p:commandButton id="showInforDialog" actionListener="#{bean.doSomething()}" onsuccess="stopAllPolls(); PF('dlgInfor').show();"/>
- 编写前端停止轮询函数:在页面的
<h:outputScript>标签中添加以下JS代码:
function stopAllPolls() { // 遍历所有标记了chart-poll类的Poll组件 $('.chart-poll').each(function() { // 获取组件对应的widgetVar名称 var widgetVar = $(this).data('widgetvar'); // 调用PrimeFaces客户端API停止轮询 if (PrimeFaces.widgets[widgetVar]) { PrimeFaces.widgets[widgetVar].stop(); } }); }
方法二:后端维护WidgetVar列表+动态生成JS执行
如果需要更精准的控制(比如后续还要恢复轮询),可以在后端统一管理所有Poll的标识:
- 给Poll设置唯一WidgetVar:基于循环索引或图表ID生成唯一的widgetVar名称:
<c:forEach var="chart" items="#{bean.charts}" varStatus="status"> <p:poll interval="#{chart.timeRefresh}" listener="#{bean.updateChart(chart)}" widgetVar="poll_#{status.index}" /> <div>..draw one-by-one chart here.</div> </c:forEach>
- 后端Bean中维护WidgetVar列表:在你的业务Bean里添加列表存储所有Poll的标识,并在按钮触发时生成停止轮询的JS代码:
import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; import org.primefaces.context.RequestContext; @ManagedBean @ViewScoped public class YourBean { private List<String> pollWidgetVars = new ArrayList<>(); private List<Chart> charts; // 页面初始化时填充Poll标识列表 public void init() { for (int i = 0; i < charts.size(); i++) { pollWidgetVars.add("poll_" + i); } } // 按钮绑定的业务方法 public void doSomething() { // 动态生成停止所有轮询的JS代码 StringBuilder jsBuilder = new StringBuilder(); for (String widgetVar : pollWidgetVars) { jsBuilder.append("if(PrimeFaces.widgets['") .append(widgetVar) .append("']) PrimeFaces.widgets['") .append(widgetVar) .append("'].stop();"); } // 执行生成的JS RequestContext.getCurrentInstance().execute(jsBuilder.toString()); } // 图表列表的getter/setter public List<Chart> getCharts() { return charts; } public void setCharts(List<Chart> charts) { this.charts = charts; } }
- 按钮保持原有定义:因为停止逻辑已经在后端动态生成并执行,按钮无需额外前端事件:
<p:commandButton id="showInforDialog" actionListener="#{bean.doSomething()}" onsuccess="PF('dlgInfor').show();"/>
额外提示:恢复轮询的方法
如果需要在对话框关闭后恢复所有图表的轮询,只需要把上述代码中的stop()替换为start()即可,比如:
function startAllPolls() { $('.chart-poll').each(function() { var widgetVar = $(this).data('widgetvar'); if (PrimeFaces.widgets[widgetVar]) { PrimeFaces.widgets[widgetVar].start(); } }); }
然后在对话框的onHide事件中调用:
<p:dialog id="dlgInfor" widgetVar="dlgInfor" onHide="startAllPolls();"> <!-- 对话框内容 --> </p:dialog>
内容的提问来源于stack exchange,提问作者Trương Huy
相关产品推荐
相关产品推荐

