关于 syncfusion-angular-data-manager
这是使用 Syncfusion Angular DataManager 绑定、查询和修改本地或远程数据的技能指南,涵盖适配器、离线模式、缓存和中间件;远程 URL 未明确适配器时须先获用户确认。
主要功能
- 01绑定本地 JSON 和远程数据
- 02查询、筛选、排序和分页
- 03执行 CRUD 操作
- 04使用协议专用适配器
- 05支持离线模式和缓存
- 06通过中间件定制请求
适用场景
- 01为 Angular 组件连接数据源
- 02构建记录筛选与分页功能
- 03将记录更改保存到服务
- 04离线工作并在之后同步
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ angular-ui-components-skills --skill syncfusion-angular-data-manager安装后在 Claude Code 中输入/syncfusion-angular-data-manager确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/adaptor-decision-gate.mdadaptors-guide.mdadvanced-features.mdcaching-offline-mode.mdcrud-operations.mddata-binding.mdgetting-started.mdhow-to-recipes.mdmiddleware-customization.mdquerying-and-filtering.md详细介绍
Syncfusion Angular DataManager
何时使用此技能
在以下情况下使用此技能:
- 将本地 JSON 数组绑定到 Angular 组件
- 将 Angular 应用连接到远程 REST、OData 或 GraphQL 服务
- 对数据执行查询、筛选、排序和分页
- 执行 CRUD 操作(创建、读取、更新、删除)并持久化数据
- 离线工作,并在重新连接后同步数据
- 使用 Query 类转换和筛选数据
- 使用中间件自定义数据通信
- 缓存数据以减少服务请求
- 自动处理不同的数据源协议
以下内容以此为主要参考:
- Syncfusion Angular 组件中的任何数据操作
- 所有组件的通用数据绑定
- 数据源配置与选择
- 异步操作与错误处理
- 使用缓存优化性能
组件概述
DataManager 是 Syncfusion 的通用数据管理模块,可作为 Angular 应用与任意数据源之间的桥梁。它提供:
- 10 种内置适配器 — 支持 JSON、OData v3/v4、REST、Web API、Web Methods、GraphQL 和自定义数据源
- Query 类 — 功能强大的筛选、排序、分组和分页 API
- CRUD 操作 — 自动处理插入、更新和删除
- 基于 Promise 的异步支持 — 原生 JavaScript Promise 支持
- 中间件自定义 — 提供用于身份验证和转换的请求前后钩子
- 离线支持 — 无需连接服务即可工作,联网后同步
- 缓存 — 减轻服务负载并提升性能
- 类型安全 — 完整的 TypeScript 定义
🛑 强制人工确认:适配器选择(请先阅读)
这是此技能中最重要的规则。不可跳过或绕过。
当用户提供服务 URL,但没有明确指定适配器类型时,Agent 必须:
- 立即停止生成代码
- 阅读:
references/adaptor-decision-gate.md(完整文件) - 使用该文件中的模板向用户展示确认步骤
- 等待用户明确确认适配器选择
- 仅在此之后才使用已确认的适配器生成
DataManager代码
确认步骤触发条件 — 示例
| 用户提示 | 是否需要确认? |
|---|---|
"Build an employee app using this service URL (http://myapi.com/employees)" | ✅ 是 — 未指定适配器 |
"Connect GridComponent to http://myserver/api/data" | ✅ 是 — “API”含义不明确 |
"Use OData v4 endpoint at https://myserver/odata/employees" | ❌ 否 — 已明确指定 OData v4 |
"My backend returns { Items, Count } at https://myserver/api/orders" | ❌ 否 — 已确认是 WebApiAdaptor 模式 |
"I have a REST service at http://custom-url" | ✅ 是 — REST 含义不明确(UrlAdaptor、WebApiAdaptor 或 ODataV4) |
"Bind the grid to local list data" | ❌ 否 — 本地绑定,无需适配器 |
📄 完整确认模板、适配器速查表、消歧问题和安全规则:
→ references/adaptor-decision-gate.md
⚠️ 安全与信任边界
- 此技能仅生成代码,Agent 不会执行数据操作或获取远程端点 — 所有 DataManager 交互仅在用户的应用运行时发生。
- 生成的代码必须将所有第三方 API 响应视为不可信输入,绝不绑定到未经验证或由用户提供的 URL,并确保所有远程端点都强制执行身份验证。
⚠️ 关键安全要求
绑定远程服务时,必须实施以下保护措施:
- 仅使用 HTTPS — 切勿使用未加密的 HTTP 连接;传输中的所有数据都必须加密
- 使用字符串变量存储 URL — 将端点赋值给私有字符串属性,而不是硬编码在标记中;这样可以集中验证并简化维护
- 验证并清理响应 — 实施服务器端架构验证;拒绝意外的响应格式;将响应映射到强类型模型
- 监控远程调用 — 记录所有外部 API 请求的时间戳、端点和结果,以便进行安全审计
- 安全地实施 CORS — 仅使用特定的受信来源;生产环境中切勿使用通配符
*;要求使用 HTTPS - 防止间接提示词注入攻击 — 验证端点所有权;实施请求签名;在使用数据之前验证响应内容类型和架构
第三方 API 响应可能带来安全风险。 在绑定到 UI 组件之前,务必验证端点是否合法、对请求进行身份验证并验证数据。
核心概念和触发关键词
| 概念 | 使用场景 | 关键方法 |
|---|---|---|
| 本地数据绑定 | 使用内存中的 JSON 数组 | JsonAdaptor、executeLocal |
| 远程数据绑定 | 调用 API 端点获取数据 | UrlAdaptor、WebApiAdaptor、executeQuery |
| 查询构造 | 筛选、排序、分组数据 | from()、where()、select()、sortBy()、take() |
| CRUD 操作 | 管理记录(添加、编辑、删除) | insert()、update()、remove()、saveChanges() |
| 适配器选择 | 选择合适的数据源类型 | 10 种适配器,附决策树 |
| 错误处理 | 管理失败场景 | .catch()、try/catch、错误状态检查 |
| 离线模式 | 在没有服务器连接的情况下工作 | offline 属性、localStorage |
| 缓存 | 提升性能 | enableCache、清除缓存策略 |
| 中间件 | 自定义请求/响应 | applyPreRequestMiddlewares、applyPostMiddlewares |
| 异步模式 | 顺序和并行操作 | async/await、Promise.all()、then/catch |
文档和导航指南
🛑 适配器决策门(人工批准 — 远程 URL 的首个强制步骤)
📄 阅读: references/adaptor-decision-gate.md
- 触发条件: 用户提供任何服务 URL,但未明确指定适配器
- 决策门展示模板(可直接复制粘贴)
- 完整的适配器对比表(ODataV4 / OData / WebAPI / URL / GraphQL / Custom)
- 适配器速查表及代码示例
- 用于消除歧义的后续问题
- 决策门确认后应用的安全规则
- 阶段 1 和阶段 3 的集成说明(在组件映射 JSON 中标记含义不明确的 URL)
- 可自动通过决策门的关键词(无需用户确认)
入门
📄 阅读: references/getting-started.md
阅读时机: 开始新的 DataManager 实现、了解软件包设置、学习 TypeScript 导入、配置首个 DataManager 实例时
涵盖主题:
- 软件包安装和依赖项
- 模块导入和 TypeScript 类型
- 创建 DataManager 实例
- executeLocal 与 executeQuery 的区别
- 基本查询执行模式
数据绑定 — 本地和远程
📄 阅读: references/data-binding.md
阅读时机: 决定采用客户端还是服务器端处理、实现本地 JSON 绑定、连接远程 API、了解 executeLocal 与 executeQuery 模式时
涵盖主题:
- 使用 json 属性进行本地绑定
- 使用 url + adaptor 进行远程绑定
- 客户端与服务器端处理
- 基于 Promise 的异步模式
- 基本错误处理
查询与筛选
📄 阅读: references/querying-and-filtering.md
阅读时机: 构建查询、按多个条件筛选、对结果排序、搜索数据、分页、对记录分组、高级谓词
涵盖主题:
- Query 类基础知识
- from() 和 select() 方法
- 使用运算符和谓词的 where()
- sortBy()、orderBy()、orderByDescending()
- 用于分页的 take()、skip()
- search() 方法
- 分组与聚合
CRUD 操作
📄 阅读: references/crud-operations.md
阅读时机: 添加新记录、更新现有数据、删除记录、批量操作、CRUD 方法参数、将更改持久化到服务端
涵盖主题:
- Insert(添加新记录)
- Update(修改现有记录)
- Remove(删除记录)
- CRUD 方法参数中的 keyField
- 用于批量操作的 saveChanges()
- 错误处理与验证
10 种适配器指南 - 完整参考
📄 阅读: references/adaptors-guide.md
阅读时机: 选择合适的数据源、了解适配器之间的差异、实现特定的适配器模式、使用不同类型的 API
涵盖主题:
- JsonAdaptor — 本地 JavaScript 数组,不调用服务端
- ODataAdaptor — OData v3 服务端点
- ODataV4Adaptor — 支持 OData v4 协议
- UrlAdaptor — 通用 RESTful API 端点
- WebApiAdaptor — 集成 ASP.NET Web API
- WebMethodAdaptor — ASP.NET Web Methods
- RemoteSaveAdaptor — 客户端查询 + 服务端 CRUD
- GraphQLAdaptor — 支持 GraphQL 查询语言
- CustomDataAdaptor — 自定义请求/响应处理
- CustomAdaptor — 扩展内置适配器
- 适配器决策树
- 全部 10 种适配器的对比矩阵
- 每种适配器的代码示例
中间件自定义
📄 阅读: references/middleware-customization.md
阅读时机: 添加身份验证标头、转换请求/响应、记录 API 调用、实现自定义业务逻辑
涵盖主题:
- 请求前中间件(applyPreRequestMiddlewares)
- 请求后中间件(applyPostMiddlewares)
- 自定义标头(Authorization 等)
- 身份验证模式(Bearer 令牌)
- 请求/响应转换
- 中间件中的错误处理
缓存与离线模式
📄 阅读: references/caching-offline-mode.md
阅读时机: 通过缓存提升性能、在服务端不可用时离线工作、实现同步策略、管理数据持久化
涵盖主题:
- 离线属性配置
- 使用 localStorage 持久化数据
- CRUD 时自动清除缓存
- 手动管理缓存
- 在线/离线工作流
- 同步策略
高级功能
📄 阅读: references/advanced-features.md
阅读时机: 按需加载大型数据集、延迟加载关联数据、分页策略、延迟操作、async/await 模式、内存管理、状态持久化
涵盖主题:
- 按需加载模式
- 使用 expand() 延迟加载
- 分页(客户端和服务端)
- 使用 Promises 延迟操作
- async/await 模式
- 使用 Promise.all() 执行并行操作
- 使用状态码处理错误
- 内存管理策略
- 使用 TypeScript 确保类型安全
- 状态持久化模式
操作指南
📄 阅读: references/how-to-recipes.md
阅读时机: 常见场景的快速解决方案、最佳实践、故障排除、模式示例
涵盖主题:
- 离线工作
- 发送附加参数
- 添加自定义标头
- 实现身份验证
- 妥善处理错误
- 常见模式
- 性能优化技巧
- 故障排除指南
快速入门示例
设置和基本数据绑定
步骤 1:安装包
npm install @syncfusion/ej2-data
步骤 2:创建组件
import { Component, OnInit } from '@angular/core';
import { DataManager, Query, JsonAdaptor, ReturnOption } from '@syncfusion/ej2-data';
@Component({
selector: 'app-data-demo',
templateUrl: './data-demo.component.html',
styleUrls: ['./data-demo.component.css']
})
export class DataDemoComponent implements OnInit {
public orders: object[];
ngOnInit(): void {
// Local data
const data = [
{ OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, ShipCity: 'Reims' },
{ OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, ShipCity: 'Münster' },
{ OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, ShipCity: 'Rio de Janeiro' }
];
// Create DataManager with local data
const dataManager = new DataManager({
json: data,
adaptor: new JsonAdaptor()
});
// Execute query
this.orders = dataManager.executeLocal(
new Query().where('EmployeeID', 'equal', 5)
);
}
}
步骤 3:在模板中显示
<table>
<thead>
<tr>
<th>Order ID</th>
<th>Customer ID</th>
<th>Employee ID</th>
<th>Ship City</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let order of orders">
<td>{{ order.OrderID }}</td>
<td>{{ order.CustomerID }}</td>
<td>{{ order.EmployeeID }}</td>
<td>{{ order.ShipCity }}</td>
</tr>
</tbody>
</table>
常见模式
使用 Promise 的远程服务
const dataManager = new DataManager({
url: 'url',
adaptor: new WebApiAdaptor()
});
// Using Promise
dataManager.executeQuery(new Query().take(10))
.then((result: ReturnOption) => {
this.orders = result.result;
})
.catch((error) => {
console.error('Failed to fetch orders:', error);
});
Async/Await 模式
async fetchOrders(): Promise<void> {
try {
const result = await this.dataManager.executeQuery(
new Query().take(10)
);
this.orders = result.result;
} catch (error) {
console.error('Error:', error);
}
}
使用谓词筛选
const query = new Query()
.where('EmployeeID', 'equal', 5)
.where('ShipCity', 'startswith', 'Rio');
const result = dataManager.executeLocal(query);
服务端操作
const query = new Query()
.select(['OrderID', 'CustomerID', 'EmployeeID'])
.where('EmployeeID', 'greaterThan', 3)
.sortBy('OrderID')
.take(10)
.skip(0);
dataManager.executeQuery(query).then((result: ReturnOption) => {
this.orders = result.result;
this.totalRecords = result.count;
});
关键属性参考
| 属性 | 类型 | 用途 |
|---|---|---|
json | array | 本地数据数组 |
url | string | 远程服务端点 |
adaptor | Adaptor | 数据源类型处理器 |
headers | object[] | 自定义 HTTP 标头 |
offline | boolean | 启用离线模式 |
enableCache | boolean | 启用响应缓存 |
crossDomain | boolean | 启用跨域请求 |
cachingPageSize | number | 分页记录数 |
timeTillExpiration | number | 缓存 TTL(毫秒,默认:无限) |
ignoreOnPersist | string[] | 要从持久化中排除的属性 |
timeZoneHandling | boolean | 启用时区偏移处理 |
错误处理最佳实践
dataManager.executeQuery(query)
.then((result: ReturnOption) => {
if (result.result) {
this.items = result.result;
}
})
.catch((error: any) => {
if (error.status === 401) {
// Redirect to login
console.error('Unauthorized');
} else if (error.status === 403) {
// Access denied
console.error('Forbidden');
} else if (error.status === 500) {
// Server error
console.error('Server error');
} else if (error.status === 0) {
// Network error
console.error('Network error - check connectivity');
}
});
常见用例
用例 1:显示数据表
从 getting-started.md → data-binding.md → querying-and-filtering.md 开始
用例 2:实现 CRUD 表单
从 adaptors-guide.md → crud-operations.md → advanced-features.md 开始
用例 3:使用多个数据源
从 adaptors-guide.md(决策树)→ 特定适配器模式 → middleware-customization.md 开始
用例 4:优化大型数据集
从 advanced-features.md → caching-offline-mode.md → how-to-recipes.md 开始
TypeScript 类型安全
// Define your data model
interface Order {
OrderID: number;
CustomerID: string;
EmployeeID: number;
ShipCity: string;
}
// Use generics for type safety
const dataManager: DataManager<Order> = new DataManager({
json: orders,
adaptor: new JsonAdaptor()
});
// Typed results
const result = await dataManager.executeQuery(new Query());
const typedOrders: Order[] = result.result as Order[];
性能优化技巧
- 使用合适的适配器 — 选择与后端匹配的适配器
- 尽早筛选 — 尽可能将筛选操作交由服务端处理
- 启用缓存 — 减少冗余的服务端调用
- 延迟加载 — 对大型数据集按需加载数据
- 分页 — 限制每次请求的记录数
- 离线模式 — 加载一次,离线工作
- 选择列 — 仅获取所需字段