EmberJS: обновление модели данных не обновляет связанные вычисленные свойства

Допустим, существует маршрут с возможностью обновления своих данных по запросу пользователя (предположим, что серверная часть возвращает разные данные для одного и того же вызова, возможно, это данные о запасах или просто случайные числа).

export default Ember.Route.extend({
  model() {
    return this.get('store').findAll('foo');
  },

  actions: {
    invalidateModel() {
      this.refresh();
    }
  }
});

Теперь компонент, использующий эту модель напрямую, обновит свой вид, как и ожидалось.

Model: {{#each model as |m|}}{{m.bar}}{{/each}}
<button {{action "refreshModel"}}>Refresh model</button>

Но если компонент использует вычисленное свойство, наблюдающее модель, обновления не выполняются.

шаблон

Model: {{#each computedModel as |m|}}{{m}}{{/each}}
<br>
<button {{action "refreshModel"}}>Refresh model</button>

Составная часть

computedModel: Ember.computed('model', function() {
  return this.get('model').map(function(m) {
    return `Computed: ${m.data.bar}`;
  });
}),

Для полного воспроизведения, вы можете проверить: https://github.com/myartsev/ember-computed-properties-on-data-model

Последний коммит - это нерабочий случай вычисляемых свойств.
Предыдущий коммит - это когда все работает правильно при непосредственном использовании модели.

Что мне не хватает?

2 ответа

Решение
computedModel: Ember.computed('model.@each.bar', function() {
  return this.get('model').map(function(m) {
    return `Computed: ${m.data.bar}`
  });
})

Закрыть петлю; Ответ @Subtletree был очень близок, и это заставило меня задуматься о правильном пути.

Разница была неуловимой, но достаточно важной, model.[] будет работать только при изменении размера возвращаемых данных; элементы добавляются или удаляются. В моем случае размер возвращаемых данных оставался постоянным, обновлялось только его значение. Таким образом, правильным способом было прослушать зависимый ключ, который вы ищете, в данном случае, "model.@ Each.bar".

Ваше вычисленное свойство прослушивает изменения самого массива. Попробуйте прослушать изменения элементов массива с помощью model.[]

https://guides.emberjs.com/v2.15.0/object-model/computed-properties-and-aggregate-data/

computedModel: Ember.computed('model.[]', function() {
  return this.get('model').map(function(m) {
    return `Computed: ${m.data.bar}`;
  });
}),

ОБНОВИТЬ

Вот пример, показывающий, что вышеуказанное решение решает проблему.

Если это не работает с вашей стороны, то есть проблема с тем, что возвращает ваш API.

Согласно моим комментариям о том, как отправить действия. Вы используете двухлетний синтаксис из Ember 1.13, с которым я не знаком.

Я предлагаю вам прочитать документы для версии, которую вы используете Ember 2.15

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