You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ember中如何判断peekAll是否返回了模型?

解决Ember Data中query请求的缓存与peekAll判断问题

首先,你遇到的.content.length问题是因为peekAll返回的是DS.RecordArray,content是Ember Data内部的私有属性,不应该直接访问。正确的做法是用length属性(Ember 3.x+支持直接点访问,低版本用get('length'))来判断是否有记录:

let positions = this.store.peekAll('position');
if (positions.length === 0) {
  // 这里发起API请求
}

不过这只是判断本地有没有任何position记录,而你用的是query(带特定条件的查询),Ember Data默认不会像findAll那样自动缓存query的结果,每次调用都会发起新请求,所以需要手动实现符合你查询条件的缓存逻辑:

方案一:手动筛选本地缓存记录

如果你的查询条件比较简单(比如等于某个字段值),可以先从本地store中筛选出符合条件的记录,再决定是否发起请求:

// 假设你的查询条件是 { department: 'engineering' }
const queryParams = { department: 'engineering' };

// 从本地缓存筛选符合条件的记录
const cachedPositions = this.store.peekAll('position').filter(record => {
  return record.get('department') === queryParams.department;
});

if (cachedPositions.length === 0) {
  // 没有符合条件的缓存记录,发起API请求
  return this.store.query('position', queryParams).then(positions => {
    // 处理返回的数据
    return positions;
  });
} else {
  // 使用本地缓存的记录
  return cachedPositions;
}

这种方式适合简单的查询逻辑,但如果你的查询涉及后端复杂处理(比如分页、模糊搜索、多条件组合),本地筛选可能和后端结果不一致,这时候可以用下面的方案。

方案二:用自定义服务缓存查询结果

创建一个专门的缓存服务,把query的结果按查询参数缓存起来,避免重复请求:

首先创建缓存服务:

// app/services/query-cache.js
import Service from '@ember/service';

export default class QueryCacheService extends Service {
  // 用Map存储缓存,key是字符串化的查询参数,value是查询结果
  cache = new Map();

  getCachedQuery(store, modelName, query) {
    const cacheKey = JSON.stringify({ modelName, query });
    // 检查缓存中是否已有结果
    if (this.cache.has(cacheKey)) {
      return Promise.resolve(this.cache.get(cacheKey));
    }
    // 没有缓存就发起请求,并存入缓存
    return store.query(modelName, query).then(results => {
      this.cache.set(cacheKey, results);
      return results;
    });
  }

  // 可选:提供清空缓存的方法,当数据更新时调用
  clearCache(modelName, query) {
    const cacheKey = JSON.stringify({ modelName, query });
    this.cache.delete(cacheKey);
  }
}

然后在路由中使用这个服务:

// app/routes/your-route.js
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class YourRoute extends Route {
  @service queryCache;

  model() {
    const queryParams = { department: 'engineering' };
    // 先检查本地有没有符合条件的记录
    const cachedRecords = this.store.peekAll('position').filter(record => {
      return record.get('department') === queryParams.department;
    });
    if (cachedRecords.length > 0) {
      return cachedRecords;
    }
    // 没有的话调用缓存服务发起请求
    return this.queryCache.getCachedQuery(this.store, 'position', queryParams);
  }
}

注意事项

  • 当你的position记录有更新、新增或删除时,记得调用clearCache方法清空对应查询的缓存,避免展示过时数据。
  • 如果你的查询参数包含动态值(比如当前用户ID),字符串化后的key会自动区分不同的查询,不用担心缓存混淆。

内容的提问来源于stack exchange,提问作者user6506263

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:49:15