Как передать объект @tracked из хука модели маршрута Ember - PullRequest
0 голосов
/ 03 августа 2020

У меня двоякий вопрос:

  1. Где лучше всего разместить какой-нибудь лог опроса c - в файле маршрута, верно?

  2. Как передать это постоянно обновляемое значение из маршрута в некоторый дочерний компонент? Обозначение некоторой переменной как «@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 , который имитирует то, что я пытаюсь сделать. Я попытался принудительно выполнить повторное вычисление, переназначив всю переменную, но это не сработало.

Этот вопрос является более глубоким погружением из моего исходного вопроса здесь .

1 Ответ

2 голосов
/ 03 августа 2020

Вы возвращаете ссылку на объект, хранящийся в this.recent в хуке модели. Но метод getRecent не изменяет этот объект, а заменяет this.recent. После первого выполнения метода getRecent модель маршрута и this.recent больше не являются одним и тем же объектом. Модель маршрута, к которой вы можете получить доступ через this.modelFor(this.routeName), является начальным значением, а this.recent - новым значением.

Вместо этого вы хотите изменить объект, возвращаемый обработчиком модели.

Объект, указанный в вашем примере, имеет фиксированную схему. Это позволяет вам пометить свойство A как отслеживаемое:

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

В настоящее время вы возвращаете значение this.recent в хуке вашей модели. Но вместо того, чтобы перезаписывать его в методе getRecent, вы изменяете только значение его свойства A:

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

Если вы не знаете схему объекта, возвращаемого в хуке модели, или если вы имеете дело с массивом, это немного сложнее. У вас не было бы собственности, которую можно было бы украсить @tracked. В этом случае я бы рекомендовал использовать пакет tracked-built-ins.

Для массивов вы также можете вернуться к устаревшему MutableArray из @ember/array/mutable пакета. Но в этом случае вы должны убедиться, что используете специальные методы для управления массивом (например, pushObject вместо push).

...