目前,将商品添加到商店中时,我在路线中使用过滤服务器端的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正在重新加载而查询不在。
答案 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()
重新运行所有路由钩子。
一些我认为有帮助的特定评论/示例: