如何从 Ember 路由模型挂钩传递 @tracked 对象

How to pass a @tracked object from an Ember route model hook

我的问题有两个:

  1. 放置某种轮询逻辑的最佳位置 - 在路由文件中对吗?

  2. 如何将这个不断更新的值从 Route 传递给某个子组件?将一些变量标记为“@tracked”,然后通过 model 挂钩传递跟踪变量?

假设我有这样的事情:

routes/index.js

export default class IndexRoute extends Route {
  @tracked
  recent: {
    A: 0,
    ...
  },

  constructor() {
    super(...arguments);
    this.getRecent();
  }

  getRecent() {
    // poll data / fetch latest
    const {A, ...partialObject} = this.recent;
    
    this.recent = { ...partialObject, A: <some new value fetched>};;
    
    later(this, this.getRecent, 2000);
  }

  model() {
    return this.recent;
  }
}

application.hbs

<p>constantly updating "this.recent": {{ this.model.A }} </p>

我想如果我像这样使用模型挂钩,它会被跟踪并因此自动更新,但事实并非如此。我有这个示例 Ember Twiddle 可以模拟我正在尝试做的事情。我试图通过重新分配整个变量来强制重新计算,但它没有用。

这个问题是我 的更深入的探讨。

您在模型挂钩中 return 引用存储在 this.recent 中的对象。但是 getRecent 方法不会更改该对象,而是会覆盖 this.recent。在第一次执行 getRecent 方法后,路由模型和 this.recent 不再是同一个对象。路由的型号,可以通过this.modelFor(this.routeName)访问到的是初始值,this.recent是新值。

您想改变从模型钩子 returned 的对象。

您的示例中给出的对象具有固定架构。这允许您将 属性 A 标记为已跟踪:

  recent: {
    @tracked A: 0,
    ...
  }

目前您 return 模型挂钩中 this.recent 的值。但不是在 getRecent 方法中覆盖它,你只是改变它的值 属性 A:

  getRecent() {  
    this.recent.A = <some new value fetched>;
    
    later(this, this.getRecent, 2000);
  }

如果您不知道在模型挂钩中 returned 的对象的架构,或者如果您正在处理一个数组,它会稍微复杂一些。你不会有 属性 来装饰 @tracked。在这种情况下,我建议使用 tracked-built-ins 包。

对于数组,您还可以从 @ember/array/mutable 包回退到旧版 MutableArray。但是在这种情况下,您必须确保使用它的自定义方法来操作数组(例如 pushObject 而不是 push)。