如何在Ember中使用本地JSON文件替代教程中的Mirage?
用本地JSON替代Mirage获取数据的Ember实现方案
嘿,我来帮你搞定这个问题!作为Ember新手,刚从Mirage切换到本地静态数据确实容易摸不清门路,我一步步给你拆解怎么做:
1. 准备本地JSON文件
首先,Ember的public文件夹是专门存放静态资源的目录,我们可以在这里模拟API接口的结构:
- 在项目根目录的
public文件夹下新建api子文件夹(对应你原来Mirage里的/api命名空间) - 在
public/api里创建rentals.json文件,把你Mirage代码里的rentals数组按照JSON格式放进去,注意要和原来的结构一致(保持data包裹数组的格式):
{ "data": [ { "id": "1", "attributes": { "title": "Lakefront Cabin", "area": "Adirondacks", // 其他你需要的属性... } }, { "id": "2", "attributes": { "title": "Mountain Loft", "area": "Rocky Mountains", // 其他属性... } } // 更多房源数据... ] }
如果你需要支持单个房源的详情请求(对应原来的/api/rentals/:id),有两种方式:
- 方式一:在
public/api下新建rentals子文件夹,为每个房源创建单独的JSON文件,比如public/api/rentals/1.json,内容是单个房源的data结构:{ "data": { "id": "1", "attributes": { "title": "Lakefront Cabin", "area": "Adirondacks", // 完整属性... } } } - 方式二:后续通过前端逻辑从列表JSON里筛选单个数据(下面会提到)
2. 调整数据请求逻辑
接下来分两种场景处理,根据你是否使用Ember Data来选择:
场景A:不使用Ember Data(新手快速上手)
如果只是简单获取数据,直接用原生fetch API就行,比如在你的路由文件(比如app/routes/rentals.js)里修改model钩子:
import Route from '@ember/routing/route'; export default class RentalsRoute extends Route { async model(params) { // 获取房源列表 if (!params.id) { let response = await fetch('/api/rentals.json'); let data = await response.json(); // 处理area查询参数过滤(对应原来Mirage的逻辑) if (this.paramsFor('rentals').area) { return data.data.filter(rental => rental.attributes.area.toLowerCase().includes(this.paramsFor('rentals').area.toLowerCase()) ); } return data.data; } // 获取单个房源详情 else { let response = await fetch('/api/rentals.json'); let data = await response.json(); return data.data.find(rental => rental.id === params.id); // 如果用了单独的详情JSON文件,就改成 fetch(`/api/rentals/${params.id}.json`) } } }
场景B:使用Ember Data(保持原有代码风格)
如果你之前用Ember Data的store来获取数据,只需要修改适配器来指向本地JSON:
- 创建
app/adapters/application.js文件,替换默认适配器逻辑:
import JSONAPIAdapter from '@ember-data/adapter/json-api'; export default class ApplicationAdapter extends JSONAPIAdapter { // 对应原来的/api命名空间 namespace = 'api'; // 处理列表查询(支持area过滤) async query(store, type, query) { let response = await fetch('/api/rentals.json'); let data = await response.json(); if (query.area) { const filtered = data.data.filter(rental => rental.attributes.area.toLowerCase().includes(query.area.toLowerCase()) ); return { data: filtered }; } return data; } // 处理单个房源查询 async findRecord(store, type, id) { // 方式一:从列表JSON里筛选 let response = await fetch('/api/rentals.json'); let data = await response.json(); const record = data.data.find(rental => rental.id === id); return { data: record }; // 方式二:如果用了单独的详情JSON文件,替换成下面的代码 // let response = await fetch(`/api/rentals/${id}.json`); // return response.json(); } }
这样你原来的store调用代码(比如this.store.findAll('rental')、this.store.findRecord('rental', id))完全不用改,适配器会自动帮你请求本地JSON并处理数据。
3. 清理Mirage(可选)
如果你确定不再需要Mirage,可以删除mirage/config.js文件,或者注释掉里面的所有代码,避免和本地JSON请求冲突。
内容的提问来源于stack exchange,提问作者Xeno
相关产品推荐
相关产品推荐

