You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过按钮点击事件停止所有p:poll组件?附多图表场景示例

如何停止所有PrimeFaces Poll组件的点击事件处理方案

针对你提到的场景——拥有多个不同刷新间隔的p:poll绑定图表,需要在点击按钮时停止所有轮询操作,这里提供两种实用的实现方式:

方法一:统一样式类+前端JS遍历控制

这种方式无需额外维护后端变量,纯前端就能快速实现:

  1. 修改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>
  1. 调整按钮事件逻辑:在按钮的onsuccess(或onclick,根据你的触发时机需求)中调用自定义JS函数,同时保留原有弹窗逻辑:
<p:commandButton 
    id="showInforDialog" 
    actionListener="#{bean.doSomething()}" 
    onsuccess="stopAllPolls(); PF('dlgInfor').show();"/>
  1. 编写前端停止轮询函数:在页面的<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的标识:

  1. 给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>
  1. 后端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; }
}
  1. 按钮保持原有定义:因为停止逻辑已经在后端动态生成并执行,按钮无需额外前端事件:
<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:48:25