0

我的问题有两个:

  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可以模拟我正在尝试做的事情。我试图通过重新分配整个变量来强制重新计算,但它没有用。

这个问题比我最初的问题更深入。

4

1 回答 1

3

You are returning a reference to object stored in this.recent in your model hook. But the getRecent method does not change that object but overrides this.recent. After the first execution of getRecent method the model of the route and this.recent aren't the same object anymore. The model of the route, which you can access through this.modelFor(this.routeName) is the initial value and this.recent is the new value.

You want to mutate the object returned from model hook instead.

The object given in your example has a fixed schema. This allows you to mark the property A as tracked:

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

As currently you return the value of this.recent in your model hook. But instead of overwriting it in getRecent method, you are only changing the value of it's property A:

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

If you don't know the schema of the object returned in model hook or if you are dealing with an array, it's a little bit more complicated. You wouldn't have a property to decorate with @tracked. I would recommend to use the tracked-built-ins package in that case.

For arrays you can also fallback to legacy MutableArray from @ember/array/mutable package. But you must make sure in that case that you use it's custom methods to manipulate the array (e.g. pushObject instead of push).

于 2020-08-03T13:21:49.930 回答