Ember Data概述 #
一、Ember Data简介 #
Ember Data是Ember.js的官方数据持久化库,提供了完整的数据管理解决方案。
1.1 核心功能 #
- 数据模型定义
- 数据关系管理
- 数据持久化
- 缓存管理
- 与后端API交互
1.2 架构概览 #
text
┌─────────────────────────────────────────────────────────┐
│ Ember Data │
├─────────────────────────────────────────────────────────┤
│ │
│ Store ←→ Adapter ←→ Serializer ←→ Backend API │
│ │ │
│ ▼ │
│ Model (Record) │
│ │ │
│ ▼ │
│ 应用组件/模板 │
│ │
└─────────────────────────────────────────────────────────┘
1.3 核心概念 #
| 概念 | 说明 |
|---|---|
| Store | 数据存储中心 |
| Model | 数据模型定义 |
| Adapter | 处理API请求 |
| Serializer | 数据格式转换 |
| Record | 模型实例 |
二、安装配置 #
2.1 安装 #
Ember Data默认包含在Ember CLI创建的项目中。
bash
# 查看已安装版本
ember show ember-data
2.2 配置 #
javascript
// app/adapters/application.js
import RESTAdapter from '@ember-data/adapter/rest';
export default class ApplicationAdapter extends RESTAdapter {
namespace = 'api/v1';
}
javascript
// app/serializers/application.js
import RESTSerializer from '@ember-data/serializer/rest';
export default class ApplicationSerializer extends RESTSerializer {
}
三、Store #
3.1 Store概述 #
Store是Ember Data的核心,负责管理所有数据记录。
javascript
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class PostsRoute extends Route {
@service store;
model() {
return this.store.findAll('post');
}
}
3.2 Store方法 #
javascript
// 查询所有
this.store.findAll('post');
// 查询单个
this.store.findRecord('post', 1);
// 条件查询
this.store.query('post', { category: 'tech' });
// 查询单个(条件)
this.store.queryRecord('post', { slug: 'hello-world' });
// 创建记录
const post = this.store.createRecord('post', {
title: 'New Post',
body: 'Content...',
});
// 获取所有已加载记录
this.store.peekAll('post');
// 获取单个已加载记录
this.store.peekRecord('post', 1);
四、模型定义 #
4.1 创建模型 #
bash
ember generate model post
4.2 定义属性 #
javascript
// app/models/post.js
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
export default class PostModel extends Model {
@attr('string') title;
@attr('string') body;
@attr('string', { defaultValue: '' }) excerpt;
@attr('date') createdAt;
@attr('date') updatedAt;
@attr('boolean', { defaultValue: false }) isPublished;
@attr('number') viewCount;
}
4.3 属性类型 #
| 类型 | 说明 |
|---|---|
string |
字符串 |
number |
数字 |
boolean |
布尔值 |
date |
日期 |
array |
数组 |
object |
对象 |
4.4 默认值 #
javascript
@attr('string', { defaultValue: '' }) title;
@attr('number', { defaultValue: 0 }) count;
@attr('boolean', { defaultValue: false }) active;
@attr('array', { defaultValue: () => [] }) tags;
五、数据操作 #
5.1 创建记录 #
javascript
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class PostsNewController extends Controller {
@service store;
@action
async createPost() {
const post = this.store.createRecord('post', {
title: 'My First Post',
body: 'This is the content...',
});
await post.save();
}
}
5.2 读取记录 #
javascript
// 获取所有记录
const posts = await this.store.findAll('post');
// 获取单个记录
const post = await this.store.findRecord('post', 1);
// 条件查询
const posts = await this.store.query('post', {
category: 'tech',
page: 1,
});
5.3 更新记录 #
javascript
@action
async updatePost(post) {
post.title = 'Updated Title';
await post.save();
}
5.4 删除记录 #
javascript
@action
async deletePost(post) {
await post.destroyRecord();
}
六、记录状态 #
6.1 状态检查 #
javascript
// 是否新建
post.isNew;
// 是否已保存
post.isSaved;
// 是否有未保存更改
post.hasDirtyAttributes;
// 是否正在保存
post.isSaving;
// 是否已删除
post.isDeleted;
// 是否正在删除
post.isDeleting;
// 是否有效
post.isValid;
// 是否有错误
post.hasErrors;
6.2 回滚更改 #
javascript
post.rollbackAttributes();
6.3 错误处理 #
javascript
@action
async savePost(post) {
try {
await post.save();
} catch (error) {
console.log(post.errors);
console.log(error);
}
}
七、异步关系 #
7.1 异步加载 #
javascript
// 模型定义
export default class PostModel extends Model {
@belongsTo('user', { async: true }) author;
@hasMany('comment', { async: true }) comments;
}
handlebars
{{! 模板中使用}}
<p>作者:{{await @post.author.name}}</p>
{{#each (await @post.comments) as |comment|}}
<p>{{comment.body}}</p>
{{/each}}
7.2 预加载关系 #
javascript
// 在路由中预加载
model() {
return this.store.findRecord('post', 1, {
include: 'author,comments',
});
}
八、缓存策略 #
8.1 后台重载 #
javascript
model() {
return this.store.findRecord('post', 1, {
backgroundReload: true,
});
}
8.2 强制重载 #
javascript
model() {
return this.store.findRecord('post', 1, {
reload: true,
});
}
8.3 缓存清空 #
javascript
// 清空所有缓存
this.store.unloadAll();
// 清空特定类型
this.store.unloadAll('post');
// 清空单个记录
post.unloadRecord();
九、最佳实践 #
9.1 在路由中加载数据 #
javascript
// 好的做法
export default class PostsRoute extends Route {
model() {
return this.store.findAll('post');
}
}
// 避免 - 在组件中加载数据
9.2 使用Ember Data约定 #
javascript
// 后端返回格式
{
"posts": [
{ "id": 1, "title": "Post 1" },
{ "id": 2, "title": "Post 2" }
]
}
9.3 处理错误 #
javascript
@action
error(error, transition) {
if (error.errors?.[0]?.status === '404') {
this.router.transitionTo('not-found');
}
}
十、总结 #
Ember Data核心概念:
| 概念 | 说明 |
|---|---|
| Store | 数据存储中心 |
| Model | 数据模型 |
| Adapter | API适配器 |
| Serializer | 数据序列化 |
| Record | 模型实例 |
Ember Data提供了完整的数据管理解决方案,是Ember应用的核心组件。
最后更新:2026-03-28