Как передать объект @tracked из хука модели маршрута Ember

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

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

  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 ответ

Решение

Вы возвращаете ссылку на объект, хранящийся в 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).

Другие вопросы по тегам