关于 syncfusion-javascript-data-manager
syncfusion-javascript-data-manager 是面向 TypeScript 和 JavaScript 应用的 Syncfusion DataManager 使用指南,涵盖本地与远程数据、查询和 CRUD。服务 URL 未明确适配器类型时,指南要求先由用户确认。
主要功能
- 01本地与远程数据绑定
- 02十种适配器类型
- 03筛选、排序与分页
- 04CRUD 与批量变更
- 05请求和响应中间件
- 06适配器选择确认流程
适用场景
- 01将网格绑定到本地数组或远程 API
- 02构建筛选与分页查询
- 03实现记录的新增、更新和删除
- 04为服务端点选择适配器
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ syncfusion/ javascript-ui-controls-skills --skill syncfusion-javascript-data-manager安装后在 Claude Code 中输入/syncfusion-javascript-data-manager确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/adaptor-decision-gate.mdadaptors-guide.mdadvanced-scenarios.mdapi-dataManager.mdapi-deferred.mdapi-query.mdapplying-middleware-logic.mdcrud-operations.mddata-binding.mddataManager-persistence.mdgetting-started.mdoverview.mdquerying.md详细介绍
TypeScript/JavaScript 的 DataManager — 完整指南
目录
🛑 强制人工确认:适配器选择(请先阅读)
这是本技能中最关键的规则。不可跳过或绕过。
当用户提供服务 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 组件前验证数据。
关键概念
10 种适配器类型(决策指南)
| 场景 | 适配器 | 使用时机 |
|---|---|---|
| 本地数组 | JsonAdaptor | 内存中的 JavaScript 数组,无需服务器 |
| ASP.NET Web API | WebApiAdaptor | 返回 Items/Count 格式的 ASP.NET 后端 |
| 通用 REST | UrlAdaptor | 使用 result/count 格式的标准 REST API |
| 客户端 + 服务器 | RemoteSaveAdaptor | 客户端筛选,服务器端 CRUD |
| OData v3 | ODataAdaptor | 旧版 OData v3 服务 |
| OData v4 | ODataV4Adaptor | 支持展开关联的现代 OData v4 |
| 旧版 ASP.NET | WebMethodAdaptor | ASMX Web 方法(已弃用) |
| GraphQL | GraphQLAdaptor | GraphQL 端点 |
| 自定义格式 | Custom DataAdaptor | 非标准 API 响应格式 |
| 完全控制 | CustomAdaptor | 完全覆盖适配器 |
数据绑定类型
Local Binding
├─ Direct array: new DataManager({ json: data })
├─ JsonAdaptor explicit
└─ Client-side filtering instant
Remote Binding
├─ WebApiAdaptor: ASP.NET specific
├─ UrlAdaptor: Generic REST
├─ ODataAdaptor/V4: Protocol-based
└─ Server processes Query object
查询操作
// Filter/Search
.where('field', 'operator', value) // Single condition
.where(predicate) // Complex predicate
// Sort/Order
.sortBy('field') // Ascending
.sortByDescending('field') // Descending
.orderBy('field') // Alias
// Pagination
.take(10) // Limit records
.skip(0) // Offset
// Projection
.select(['field1', 'field2']) // Column selection
// Relationships
.expand('relatedTable') // OData expand
// Grouping & Aggregation
.group('field') // Group by
.aggregate('sum', 'field') // Calculate
10 种适配器参考
决策树:应选择哪种适配器?
Does your data come from?
│
├─ JavaScript array in memory?
│ └─ JsonAdaptor
│
├─ Web Server / REST API?
│ ├─ ASP.NET Web API (backend specific)?
│ │ └─ WebApiAdaptor (Items/Count format)
│ ├─ Generic REST endpoint?
│ │ └─ UrlAdaptor (result/count format)
│ ├─ Need offline with server-side CRUD?
│ │ └─ RemoteSaveAdaptor
│ └─ Custom format (non-standard)?
│ └─ CustomDataAdaptor
│
├─ OData Service?
│ ├─ OData v3 (legacy)?
│ │ └─ ODataAdaptor
│ └─ OData v4 (modern)?
│ └─ ODataV4Adaptor (with expand)
│
├─ GraphQL Endpoint?
│ └─ GraphQLAdaptor
│
├─ Legacy ASP.NET ASMX?
│ └─ WebMethodAdaptor
│
└─ Custom/Proprietary?
├─ Custom request/response format?
│ └─ CustomDataAdaptor
└─ Need complete adaptor override?
└─ CustomAdaptor
文档导航指南
🛑 适配器决策关卡(人工审批——远程 URL 的强制第一步)
📄 阅读: references/adaptor-decision-gate.md
- 触发时机: 用户提供任何服务 URL,但未明确指定适配器
- 决策关卡展示模板(可直接复制粘贴)
- 完整的适配器对比表(ODataV4 / OData / WebAPI / URL / GraphQL / Custom)
- 适配器快速参考速查表,含代码示例
- 用于消除歧义的后续问题
- 关卡确认后应用的安全规则
- 第 1 阶段和第 3 阶段集成说明(在组件映射 JSON 中标记有歧义的 URL)
- 可自动通过关卡的关键词(无需用户确认)
📄 入门与设置
阅读: 入门指南
- 安装(@syncfusion/ej2-data)
- 浏览器要求
- 首个 DataManager 示例
- 本地数组绑定
- 远程 API 绑定
📄 了解概念
阅读: 概述
- 什么是 DataManager?
- 主要功能
- 何时使用 DataManager
- 架构
📄 数据绑定(本地与远程)
阅读: 数据绑定
- 使用 JsonAdaptor 绑定本地数组
- 远程 API(REST、OData)
- 错误处理(HTTP 0、400、401、404、500)
- Promise 模式(.then/.catch)
- async/await 示例
- 加载状态
📄 构建复杂查询
阅读: 查询
- from() - 指定资源
- where() - 15 种以上的筛选运算符(equal、contains、startswith、greaterThan 等)
- select() - 列投影
- orderBy/sortBy - 多个排序列
- take/skip - 分页
- group() - 数据分组
- aggregate() - sum、avg、count、min、max
- 基于复杂谓词的筛选
📄 CRUD:插入、更新、删除
阅读: CRUD 操作
- insert() - 单条和批量记录
- 使用 keyField 参数调用 update() 和 remove()
- remove() - 按 ID 删除
- saveChanges() - 批量混合操作
- 错误处理与验证
- 响应格式(Items/Count、result/count)
- 冲突解决
📄 10 种适配器详解
阅读: 适配器指南
- 完整的适配器决策树
- 每种适配器均包含:
- 使用时机
- 配置示例
- 用法示例
- 后端响应格式
- C# 或 JavaScript 后端模式
- 对比矩阵
- CORS 配置
📄 中间件与请求自定义
阅读: 应用中间件逻辑
- 请求前中间件(添加标头、令牌)
- 请求后中间件(转换响应)
- JWT 身份验证模式
- 自定义标头(静态和动态)
- 请求/响应转换
- 使用重试进行错误处理
- 中间件执行顺序
📄 浏览器状态持久化
阅读: 状态持久化
- enablePersistence - 保存查询状态
- 集成 localStorage
- 排除特定查询的持久化
- 重新加载时重新应用已保存的状态
📄 高级场景与优化
阅读: 高级场景
- 离线模式(仅下载一次,在客户端筛选)
- 按需加载分页
- 延迟执行(Promises)
- async/await 模式
- 内存管理
- 性能优化
- 故障排除
📄 API 参考
- executeQuery() 方法
- executeLocal() 方法
- insert()、update()、remove()
- 用于批量操作的 saveChanges()
阅读: API - Query
- 所有 Query 构建器方法
- where()、select()、from()、group()
- take()、skip()、orderBy()
- aggregate()、expand()
阅读: API - Deferred
- 基于 Promise 的异步处理
- then()、catch()、finally()
- 错误回调
快速开始
设置
import { DataManager, WebApiAdaptor, Query } from '@syncfusion/ej2-data';
const dataManager = new DataManager({
url: 'url/orders',
adaptor: new WebApiAdaptor()
});
查询示例
// Fetch with filtering & sorting
dataManager.executeQuery(
new Query()
.where('Freight', 'greaterThan', 30)
.sortByDescending('OrderDate')
.take(20)
).then((result) => {
console.log('Orders:', result.result);
console.log('Total:', result.count);
}).catch((error) => {
console.error('Error:', error);
});
CRUD 操作
// Insert (data first, then tableName)
await dataManager.insert({ CustomerID: 'VINET', Freight: 32.50 }, 'Orders');
// Update (keyField, value object, tableName)
await dataManager.update('OrderID',
{ OrderID: 10248, Freight: 45.50 },
'Orders'
);
// Delete (keyField, keyValue, tableName)
await dataManager.remove('OrderID', 10248, 'Orders');
常见错误处理
HTTP 状态码
| 状态 | 含义 | 解决方案 |
|---|---|---|
| 0 | 网络错误 | 检查互联网连接 |
| 400 | 请求错误 | 验证数据格式 |
| 401 | 未授权 | 检查身份验证令牌 |
| 403 | 禁止访问 | 验证权限 |
| 404 | 未找到 | 检查端点 URL |
| 409 | 冲突 | 数据已存在,请刷新数据 |
| 500 | 服务器错误 | 检查后端日志 |
错误处理模式
// Promise-based
dataManager.executeQuery(new Query())
.then((result) => {
// Success: result.result, result.count
})
.catch((error) => {
if (error.status === 401) {
console.error('Unauthorized - login required');
} else if (error.status === 500) {
console.error('Server error');
} else {
console.error('Error:', error.message);
}
});
// Async/Await
try {
const result = await dataManager.executeQuery(new Query());
console.log('Data:', result.result);
} catch (error) {
console.error('Error status:', error.status);
}
10 个关键属性
const config = {
url: 'api.example.com/orders', // Remote endpoint
json: localArray, // Local data array
adaptor: new WebApiAdaptor(), // Protocol handler
// Caching & Performance
enableCache: true, // Enable result caching
timeTillExpiration: 10 * 60 * 1000, // Cache TTL (10 mins, default: no expiry)
// Persistence
enablePersistence: true, // Enable state persistence
id: 'dataManager_1', // Persistence ID
ignoreOnPersist: ['temp', 'debug'], // Properties to exclude
// HTTP headers
crossDomain: true, // CORS enabled
offline: false, // Offline mode
timeZoneHandling: true // Timezone offset handling
};
框架变体
TypeScript
import { DataManager, WebApiAdaptor, Query } from '@syncfusion/ej2-data';
const dm = new DataManager({
url: 'api.example.com/orders',
adaptor: new WebApiAdaptor()
});
dm.executeQuery(new Query().take(10)).then((result) => {
console.log(result.result);
});
JavaScript (ES6)
const { DataManager, WebApiAdaptor, Query } = require('@syncfusion/ej2-data');
const dm = new DataManager({
url: 'api.example.com/orders',
adaptor: new WebApiAdaptor()
});
dm.executeQuery(new Query().take(10)).then((result) => {
console.log(result.result);
});
评论
支持 Markdown