syncfusion-angular-data-manager について
SyncfusionのAngular DataManagerでローカルまたはリモートデータをバインド、検索、変更するためのスキルガイドです。アダプター、オフライン利用、キャッシュ、ミドルウェアを扱い、リモートURLのアダプターが不明な場合はユーザーの確認を求めます。
主な機能
- 01ローカルJSONとリモートデータのバインド
- 02レコードの検索、フィルタリング、並べ替え、ページ分割
- 03CRUD操作
- 04プロトコル別アダプターの利用
- 05オフラインモードとキャッシュ
- 06ミドルウェアによるリクエストのカスタマイズ
活用シーン
- 01Angularコンポーネントをデータソースに接続
- 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 は、Angular アプリケーションとあらゆるデータソースをつなぐブリッジとして機能する、Syncfusion の汎用データ管理モジュールです。次の機能を備えています。
- 10 種類の組み込みアダプター — JSON、OData v3/v4、REST、Web API、Web Methods、GraphQL、カスタムソースをサポート
- Query クラス — 強力なフィルタリング、並べ替え、グループ化、ページング API
- CRUD 操作 — 挿入、更新、削除を自動的に処理
- Promise ベースの非同期処理 — JavaScript のネイティブ Promise をサポート
- ミドルウェアによるカスタマイズ — 認証や変換に対応するリクエスト前後のフック
- オフラインサポート — サーバーに接続せずに作業し、オンライン時に同期
- キャッシュ — サーバーの負荷を軽減し、パフォーマンスを向上
- 型安全性 — TypeScript の完全な型定義
🛑 必須の人間による確認ゲート:アダプターの決定(最初にお読みください)
これはこのスキルで最も重要なルールです。省略したり、回避したりすることはできません。
ユーザーがアダプターの種類を明示せずにサービス URL を提示した場合、エージェントは必ず次の手順を実行してください。
- コード生成を直ちに停止する
- 読む:
references/adaptor-decision-gate.md(ファイル全体) - 提示する: そのファイルのテンプレートを使用して、確認ゲートをユーザーに提示する
- 待機する: アダプターの選択について、ユーザーから明示的な確認を得る
- その後に限り: 確認済みのアダプターを使用して
DataManagerのコード生成に進む
ゲートの発動条件 — 例
| ユーザーのプロンプト | ゲートが必要か |
|---|---|
"このサービス URL(http://myapi.com/employees)を使用して従業員アプリを構築してください" | ✅ はい — アダプターの指定がありません |
"GridComponent を http://myserver/api/data に接続してください" | ✅ はい — 「API」だけでは曖昧です |
"https://myserver/odata/employees の OData v4 エンドポイントを使用してください" | ❌ いいえ — OData v4 が明示されています |
"バックエンドは https://myserver/api/orders で { Items, Count } を返します" | ❌ いいえ — WebApiAdaptor のパターンであることが確認されています |
"http://custom-url に REST サービスがあります" | ✅ はい — REST は曖昧です(UrlAdaptor、WebApiAdaptor、ODataV4 のいずれか) |
"グリッドをローカルのリストデータにバインドしてください" | ❌ いいえ — ローカルバインディングのため、アダプターは不要です |
📄 確認ゲートの完全なテンプレート、アダプターの早見表、曖昧さを解消する質問、セキュリティルール:
→ references/adaptor-decision-gate.md
⚠️ セキュリティと信頼境界
- このスキルが生成するのはコードのみです。エージェントはデータ操作を実行したり、リモートエンドポイントを取得したりしません。DataManager とのやり取りはすべて、実行時にユーザーのアプリケーション内でのみ発生します。
- 生成されたコードでは、すべてのサードパーティ API のレスポンスを信頼できない入力として扱い、検証されていない URL やユーザー提供の 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 とアダプターを使用したリモートバインディング
- クライアント側処理とサーバー側処理
- 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 メソッド
- RemoteSaveAdaptor — クライアント側のクエリ+サーバー側の CRUD
- GraphQLAdaptor — GraphQL クエリ言語のサポート
- CustomDataAdaptor — カスタムのリクエスト/レスポンス処理
- CustomAdaptor — 組み込みアダプターの拡張
- アダプターの選択ツリー
- 10 種類すべての比較表
- 各アダプターのコード例
ミドルウェアのカスタマイズ
📄 参照: references/middleware-customization.md
読むタイミング: 認証ヘッダーの追加、リクエスト/レスポンスの変換、API 呼び出しのログ記録、カスタムビジネスロジックの実装
取り上げるトピック:
- リクエスト前のミドルウェア(applyPreRequestMiddlewares)
- リクエスト後のミドルウェア(applyPostMiddlewares)
- カスタムヘッダー(Authorization など)
- 認証パターン(Bearer トークン)
- リクエスト/レスポンスの変換
- ミドルウェアでのエラー処理
キャッシュとオフラインモード
📄 参照: references/caching-offline-mode.md
読むタイミング: キャッシュによるパフォーマンス向上、サーバーが利用できない場合のオフライン作業、同期方法の実装、データ永続化の管理
取り上げるトピック:
- Offline プロパティの設定
- データ永続化のための localStorage
- CRUD 時のキャッシュの自動クリア
- 手動でのキャッシュ管理
- オンライン/オフラインのワークフロー
- 同期方法
高度な機能
📄 参照: references/advanced-features.md
読むタイミング: 大規模なデータセットのオンデマンド読み込み、関連データの遅延読み込み、ページネーション戦略、遅延操作、async/await パターン、メモリ管理、状態の永続化
取り上げるトピック:
- オンデマンド読み込みパターン
- expand() による遅延読み込み
- ページネーション(クライアント側/サーバー側)
- Promise による遅延操作
- 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[];
パフォーマンス最適化のヒント
- 適切なアダプターを使う — バックエンドに合ったアダプターを選択します
- 早めにフィルタリングする — 可能な場合はフィルタリングをサーバー側で行います
- キャッシュを有効にする — サーバーへの重複した呼び出しを減らします
- 遅延読み込み — 大規模なデータセットでは、必要に応じてデータを読み込みます
- ページネーション — リクエストごとのレコード数を制限します
- オフラインモード — 一度読み込んで、オフラインで作業します
- 列を選択する — 必要なフィールドのみを取得します