灰烬store.findAll正在重新加载视图,而store.query不是

时间:2019-06-27 12:39:17

标签: ember.js ember-data

目前,将商品添加到商店中时,我在路线中使用过滤服务器端的store.query()时不会更新视图,但是当我使用store.findAll()进行过滤时会更新视图客户端。

使用findAll过滤客户端

//route.js
model() {
return this.get('store').findAll('article');
}

//controller.js
articleSorted: computed.filterBy('model', 'isPublished', true),

并带有查询过滤服务器端

//route.js
model() {
  return this.get('store').query('article', { q: 'isPublished' }),
}

事实是findAll正在重新加载而查询不在。

我找到了,但是不明白 https://github.com/emberjs/ember.js/issues/15256

2 个答案:

答案 0 :(得分:1)

感谢您的提问。我会尽力回答,但似乎应该在《灰烬指南》中添加更多文档来解释这种情况?

本质上this.store.findAll()this.store.query()做两件非常不同的事情。 findAll()旨在表示实体的所有所有(在您的情况下为商品),因此随着商店找到更多应关注的商品,结果将自动更新是有意义的。这样做是因为它不返回文章数组,而是返回一个DS.RecordArray,它将自动更新。

另一方面,

query()旨在每次询问后端期望的结果是什么,并且通常您将许多参数传递给后端正在使用的query()调用查找或过滤结果。前端不可能确切知道后端如何解释这些查询参数,因此,当添加满足相同查询的新文章时,前端就不可能“自动更新”。

这有意义吗?您想让我更详细吗?

答案 1 :(得分:0)

使用store.query从服务器获取数据时,视图仍可以使用新的客户端创建的商店数据 进行自动更新,然后将其保存到服务器,方法是使用“实时”记录数组。

虽然store.query中的数据不是实时数据,而store.peekAll中的数据却是实时数据,所以您可以先查询,然后再利用store.peekAll进行显示。您可以在将模型设置为所查看的数据之前进行查询,或者将查询保留为模型,但可以使用所查看数据的其他一些属性进行显示。重要的部分是确保在查询商店之前已解决查询。

基于您当前问题中的代码的示例:

// route.js
beforeModel() {
  // using return ensures this hook waits for the promise to resolve before moving on
  return this.store.query('article', { q: 'isPublished' });
}

model() {
  // Queried server data should now be available to peek at locally, 
  // so we can set the model to a live version of it. Don't append filterBy here,
  // otherwise it will no longer be live.
  return this.store.peekAll('article');
}

// controller.js
// seemingly redundant filter since using query, but needed if there are other records
// in the store that shouldn't be displayed, and is recomputed when 
// a record is added or removed from the store-based model
articleSorted: filterBy('model', 'isPublished', true) // filterBy imported from '@ember/object/computed'

// template.hbs
{{#each articleSorted as |article|}}
    {{!-- this displayed list should update as new records are added to the store --}}
    {{article}}
{{/each}}

请注意,在新记录之后 被保存到服务器,可以通过其update方法或路由刷新来更新查询。这将重新运行查询并从服务器获取更新的结果。如果查询是模型,则看起来像model.update()。如果已保存到someOtherProperty,则someOtherProperty.update()。无论哪种情况,都可以使用route.refresh()重新运行所有路由钩子。

一些我认为有帮助的特定评论/示例: