能否将查询语句存入变量?及ember-simple-pagination过渡卡顿问题咨询
1. 是否可以将查询语句存储到变量中?
当然可以呀!在Ember开发里,把查询相关的配置甚至是查询返回的Promise存到变量中是非常实用的做法,既能让代码更整洁,还方便后续复用。
举几个简单的例子:
- 存储查询参数:
// 把分页参数封装成变量 const postQueryParams = { page: { number: this.get('pageNumber'), size: this.get('pageSize') } }; // 直接使用变量发起查询 this.get('store').query('post', postQueryParams).then(result => { // 处理数据 });
- 用计算属性动态生成查询参数(适合参数会变化的场景):
// 定义计算属性,pageNumber或pageSize变化时自动更新 postQueryParams: computed('pageNumber', 'pageSize', function() { return { page: { number: this.get('pageNumber'), size: this.get('pageSize') } }; }), loadPosts() { // 直接调用计算属性里的参数 this.get('store').query('post', this.get('postQueryParams')).then(result => { // 处理结果 }); }
- 甚至可以把整个查询Promise存起来,方便后续链式调用:
const fetchPostsPromise = this.get('store').query('post', { page: { number: 1, size: 20 } }); // 之后在需要的地方使用这个Promise fetchPostsPromise.then(posts => { console.log('获取到帖子:', posts); });
这样处理后,代码的可读性和可维护性都会提升不少~
2. 修复ember-simple-pagination页面过渡不流畅的问题
你的思路完全正确!当前代码里先unloadAll清空Store再请求数据,会导致页面短暂空白,过渡自然卡顿。我们只需要调整顺序,先拿到新数据,再替换旧数据,就能让页面过渡变得流畅。
修改后的完整代码:
import Component from '@ember/component'; import { computed } from '@ember/object'; import { sort } from '@ember/object/computed'; import { inject as service } from '@ember/service'; export default Component.extend({ store: service(), posts: computed(function() { return this.get('store').peekAll('post'); }), pageSize: 20, pageNumber: null, recordCount: null, sortProps: ['createdAt:desc'], sortedPosts: sort('posts', 'sortProps'), // 新增加载状态,提升用户体验 isLoading: false, loadPosts(getPageNumber) { this.set('isLoading', true); const pageSize = this.get('pageSize'); // 先请求新数据,再处理Store this.get('store').query('post', {page: {number: getPageNumber, size: pageSize}}).then((result) => { // 清空旧数据 this.get('store').unloadAll('post'); // 把新数据推回Store(query本身会存数据,但unloadAll后需要确保它们被保留) result.forEach(post => this.get('store').push(post)); this.setProperties({ 'recordCount': result.get('meta.record-count'), 'pageNumber': getPageNumber }); }).finally(() => { // 请求完成后不管成功失败都关闭加载状态 this.set('isLoading', false); }); }, init() { this._super(...arguments); this.loadPosts(1); }, actions: { getPage(getPageNumber) { this.loadPosts(getPageNumber); } } });
额外优化小技巧:
- 添加加载状态:上面的代码里加了
isLoading属性,你可以在模板里根据这个属性显示加载动画或者提示文字,让用户知道页面正在处理,不会以为页面卡住了。 - 使用
pushPayload优化性能:如果你的API返回的是Ember Data标准的Payload格式,可以用pushPayload代替逐条push,效率更高:
// 替换forEach那一行 this.get('store').pushPayload('post', result.toJSON({ includeId: true }));
- 避免重复请求:如果用户快速点击分页按钮,可以加个防抖处理,防止重复发起相同的请求。
这样调整后,页面就不会出现空白断层了,新数据会无缝替换旧数据,过渡自然流畅~
内容的提问来源于stack exchange,提问作者elo
相关产品推荐
相关产品推荐

