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

Ember.js 3.24 LTS 组件如何实现API轮询并更新活动日志展示

问题根源

你当前的轮询逻辑仅在路由model钩子执行时返回了首次拉取的日志数据,后续递归调用pollTestActivity拿到的新数据没有同步到路由的响应式属性中,组件接收的@phaseActivityLog始终是初始的旧引用,因此不会触发视图更新。

代码修改方案

1. 调整路由逻辑

// addon/routes/single-scan/index.js 
import { later, cancel } from '@ember/runloop';
...
  async model() {
    // 首次拉取初始数据
    let phaseActivityLog = await this.store.query('phase-activity-log', testId, { reload: true });
    return { phaseActivityLog };
  }

  setupController(controller, model) {
    super.setupController(...arguments);
    // 将初始数据挂载到controller的响应式属性上
    controller.phaseActivityLog = model.phaseActivityLog;
    // 启动轮询任务
    this._startPolling(testId);
  }

  // 私有轮询方法
  async _startPolling(testId) {
    this.pollTimer = later(
      this,
      async function () {
        // 拉取最新日志数据
        const latestLogs = await this.store.query('phase-activity-log', testId, { reload: true });
        // 更新controller属性,自动触发响应式更新
        this.controller.set('phaseActivityLog', latestLogs);
        // 触发下一轮轮询
        this._startPolling(testId);
      },
      2000
    );
  }

  // 路由离开时清理定时器,避免内存泄漏
  deactivate() {
    super.deactivate(...arguments);
    if (this.pollTimer) {
      cancel(this.pollTimer);
      this.pollTimer = null;
    }
  }

2. 修改路由模板传参

将路由模板中传给组件的参数从model.phaseActivityLog改为controller上的响应式属性:

// addon/templates/single-scan/index.hbs
<SingleScan::PhaseActivityLog @phaseActivityLog={{this.phaseActivityLog}} />

3. 组件代码无需改动

你现有的组件模板逻辑可以直接复用,@phaseActivityLog更新后{{each}}会自动重新渲染最新的日志列表。

补充说明

如果你使用Ember Data且查询参数固定,store.query返回的RecordArray本身是动态响应式的,只要后台返回新数据,数组内的记录会自动更新,不需要每次替换整个数组引用,也能触发组件重渲染。上述方案是更通用的实现,兼容所有数据结构场景。

内容的提问来源于stack exchange,提问作者RonPringadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:45:03