0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

複数のWijmo FlexGridへ大量データを高速に非同期表示する処理

Posted at

JavaScriptのモダンな非同期処理を駆使して**「複数のデータソースから並列でデータを取得し、完了したものから順次Wijmo FlexGridに表示する」**という、高速かつユーザーフレンドリーな実装方法をまとめる。

1. バックエンドの準備 (@RestController)

バックエンド側でJSON形式のデータを返すAPIエンドポイントが用意されていることを前提とする。
Spring Bootでは、以下のように@RestControllerを用いて簡単に実装できる。

com/example/demo/controller/ApiController.java

@RestController
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/customers")
    public List<CustomerDto> getCustomers() {
        // 顧客データを取得する重い処理(例: 1秒かかる)
        // Thread.sleep(1000); 
        return customerService.findAll();
    }

    @GetMapping("/products")
    public List<ProductDto> getProducts() {
        // 製品データを取得する非常に重い処理(例: 3秒かかる)
        // Thread.sleep(3000);
        return productService.findAll();
    }
}

3. フロントエンド実装: HTMLの準備

まず、Wijmoライブラリを読み込み、FlexGridをホストするためのdiv要素をHTMLに配置する。

templates/grid-view.html

<!DOCTYPE html>
<html>
<head>
    <title>Wijmo FlexGrid Parallel Loading</title>
    <link href="https://cdn.grapecity.com/wijmo/5.20231.888/styles/wijmo.min.css" rel="stylesheet" />
    <script src="https://cdn.grapecity.com/wijmo/5.20231.888/controls/wijmo.min.js"></script>
    <script src="https://cdn.grapecity.com/wijmo/5.20231.888/controls/wijmo.grid.min.js"></script>
</head>
<body>
    <h1>ダッシュボード</h1>

    <h2>顧客リスト(読み込み時間: 短)</h2>
    <div id="customerGrid" style="height: 300px; margin-bottom: 20px;"></div>
    
    <h2>製品在庫(読み込み時間: 長)</h2>
    <div id="productGrid" style="height: 300px;"></div>

    <script>
        // このセクションにJavaScriptコードを記述する
    </script>
</body>
</html>

4. フロントエンド実装: JavaScriptによる並列・順次データバインド

複数のAPIリクエストを並列で実行し、完了したものから順次グリッドを更新するロジックを実装する。

Step 1: 共通化されたデータバインド関数の作成

まず、再利用性を考慮し、データ取得からバインドまでの一連の処理を一つの関数にまとめる。

/**
 * 複数のWijmo FlexGridに対し、それぞれ対応するAPIからデータを並列で非同期に取得し、
 * 【完了したものから順次】itemsSourceに設定する。
 *
 * @param {Array<object>} gridConfigs - グリッドとAPIの設定情報の配列
 * @param {wijmo.grid.FlexGrid} gridConfigs[].grid - データ設定対象のFlexGridインスタンス
 * @param {string} gridConfigs[].apiUrl - データ取得先のAPIのURL
 */
function bindDataToGridsSequentially(gridConfigs) {
    // 1. まず、すべてのグリッドのローディング表示を開始する
    gridConfigs.forEach(config => {
        config.grid.itemsSource = [];      // データソースを空にする
        config.grid.isLoading = true;      // Wijmoのローディング表示を有効化
    });

    // 2. 各グリッドに対して、データ取得処理を並列で開始する
    // forEachはawaitしないため、ループはすぐに完了し、
    // 各fetchはバックグラウンドで並列に実行される。
    gridConfigs.forEach(config => {
        fetch(config.apiUrl)
            .then(response => {
                if (!response.ok) {
                    // HTTPステータスが200番台でない場合はエラーとする
                    throw new Error(`API request failed for ${config.apiUrl} with status ${response.status}`);
                }
                return response.json();
            })
            .then(data => {
                // ★成功した場合、即座に対応するグリッドのitemsSourceを更新
                config.grid.itemsSource = data;
                console.log(`[Success] Grid updated from ${config.apiUrl}`);
            })
            .catch(error => {
                // ★失敗した場合も、即座にエラー処理を行う
                console.error(`[Failure] Could not load data for grid from ${config.apiUrl}:`, error);
                // ここで、対象グリッドの隣にエラーメッセージを表示するなどのUIフィードバックも可能
            })
            .finally(() => {
                // ★成功・失敗にかかわらず、そのグリッドのローディング表示を解除する
                config.grid.isLoading = false;
            });
    });
}

Step 2: 関数の呼び出し

ページの読み込み完了後、FlexGridのインスタンスを生成し、作成した共通関数を呼び出してデータロードを開始する。

// 上記のbindDataToGridsSequentially関数の定義に続けて記述

document.addEventListener('DOMContentLoaded', () => {

    // 1. 各FlexGridのインスタンスを生成する
    const customerGrid = new wijmo.grid.FlexGrid('#customerGrid', {
        isReadOnly: true,
        autoGenerateColumns: false,
        columns: [
            { binding: 'id', header: '顧客ID' },
            { binding: 'name', header: '顧客名' },
            { binding: 'country', header: '' }
        ]
    });

    const productGrid = new wijmo.grid.FlexGrid('#productGrid', {
        isReadOnly: true,
        autoGenerateColumns: false,
        columns: [
            { binding: 'productName', header: '製品名' },
            { binding: 'stock', header: '在庫数' },
            { binding: 'price', header: '単価', format: 'c0' }
        ]
    });

    // 2. グリッドとAPIの組み合わせを定義した設定配列を作成する
    const gridConfigs = [
        { grid: customerGrid, apiUrl: '/api/customers' },
        { grid: productGrid,  apiUrl: '/api/products' }
    ];

    // 3. 共通関数を呼び出して、データの並列ロードとバインドを開始する
    console.log('各グリッドのデータロードを開始します...');
    bindDataToGridsSequentially(gridConfigs);
});
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?