SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

最先端テクノロジーに対応した高速・軽量なJavaScript UIライブラリ「Wijmo」の活用(PR)

JavaScriptライブラリ「Wijmo」のFlexGridをReact+ASP.NET Core環境で使ってみよう

ECMAScript 5に準拠した高速・軽量なJavaScript UIライブラリ「Wijmo 5」の活用 第19回

  • このエントリーをはてなブックマークに追加

 本記事では、グレープシティのJavaScriptライブラリ「Wijmo(ウィジモ)」に含まれるグリッド部品FlexGridを、Reactと組み合わせて利用する方法を説明します。ReactとASP.NET Coreを利用するVisual Studio 2022のテンプレートをもとに、FlexGridを表示させる実装を行います。関連して、ASP.NET CoreでWeb APIを作成して、APIの戻り値をFlexGridで表示する方法も説明します。

  • このエントリーをはてなブックマークに追加

はじめに

 Wijmo(ウィジモ)は、グレープシティがHTML/JavaScript環境に向けて提供しているJavaScriptライブラリで、WebサイトやWebアプリケーションで活用できるUI部品を利用者に提供します。現状の最新版は「2021J v3」です。

図1 Wijmoの製品ページ(https://www.grapecity.co.jp/developer/wijmo)
図1 Wijmoの製品ページ

 Wijmoが提供するUI部品は、単体で利用する他に、Angular、React、Vue.jsといったJavaScriptライブラリ・フレームワークと組み合わせて利用することもできます。WijmoのUI部品は各環境でコンポーネントとしてシームレスに動作します。

 本記事では、Wijmoが提供する高機能グリッド部品FlexGridを、Reactと組み合わせたクライアント側環境および、マイクロソフトが提供するASP.NET Coreのサーバー側環境と組み合わせた実装を紹介します。Visual Studio 2022のプロジェクトテンプレートをもとに実装して、React上でFlexGridを表示させます。また、ASP.NET CoreでWeb APIを実装して、戻り値をFlexGridで表示する方法も説明します。

対象読者

  • UI部品としてWijmoの利用を検討されている方
  • Reactで利用できるUI部品を試したい方
  • ASP.NET CoreのWeb API実装について知りたい方

必要な環境

 本記事のサンプルコードは、以下の環境で動作を確認しています。

  • Windows 10 64bit版
  • Wijmo 5.20213.824
  • Microsoft Visual Studio Community 2022 17.0.5
  • Node.js 16.13.2 64bit版
  • Microsoft Edge 98.0.1108.43

 サンプルコードに含まれるソリューションファイル(*.sln)をVisual Studio 2022で開くことで、ソースコードの確認や実行が行えます。

Visual StudioでReactプロジェクトを作る

 WijmoをReactで使う準備として、まずVisual StudioでReactプロジェクトを作成して実行してみます。プロジェクトを実行して表示されるWebページ(図2)では、画面右上の「Counter」をクリックすると、ボタン押下でカウンターが増えるサンプルが表示されます。また「Fetch data」は、ASP.NET Coreで実装した天気予報のデータを模擬したWeb APIから取得したデータを表に表示するサンプルです。

図2 Visual Studio 2022で生成できるReactアプリの実行結果(P001ReactPlain)
図2 Visual Studio 2022で生成できるReactアプリの実行結果(P001ReactPlain)

 プロジェクトの作成方法を説明します。まずVisual Studioでプロジェクトを新規作成します。プロジェクトテンプレートは「React.js での ASP.NET Core」を選択します。

図3 Visual StudioでReactアプリのテンプレートを選択してプロジェクトを作成
図3 Visual StudioでReactアプリのテンプレートを選択してプロジェクトを作成

 プロジェクト名と生成先パスの設定を行った後、フレームワークの選択では「.NET 6.0」を選択し、それ以外はデフォルト設定のままで「作成」をクリックすると、図2の通り実行できるプロジェクトが生成されます。

Reactプロジェクトの概要説明

 図2のプロジェクトをもとにFlexGridの実装を追加するため、プロジェクトを構成するファイル群の概要を解説します。ソリューションファイル(P001ReactPlain.sln)と同じ階層のP001ReactPlainフォルダー(図4)内で、ClientAppフォルダーがReactを利用したクライアント側のコード、それ以外がASP.NET Coreを利用したサーバー側のコードです。Web APIはControllers配下に配置します(記事後半でWeb APIを追加実装します)。

図4 ReactプロジェクトのP001ReactPlainフォルダー(P001ReactPlain)
図4 ReactプロジェクトのP001ReactPlainフォルダー(P001ReactPlain)

 ClientAppフォルダー内(図5)には、Reactプロジェクトの定義ファイルpackage.jsonなどが存在します。aspnetcore-https.jsは開発用のSSL証明書を生成する処理のファイル、aspnetcore-react.jsは生成したSSL証明書を参照する設定ファイル(.env.development.local)を生成する処理のファイルです。publicフォルダーにはindex.htmlなどが配置されます。

図5 ReactプロジェクトのP001ReactPlain/ClientAppフォルダー(P001ReactPlain)
図5 ReactプロジェクトのP001ReactPlain/ClientAppフォルダー(P001ReactPlain)

 Reactを利用した実装の実体は、ClientApp/srcフォルダー内(図6)に存在します。

図6 ReactプロジェクトのP001ReactPlain/ClientApp/srcフォルダー(P001ReactPlain)
図6 ReactプロジェクトのP001ReactPlain/ClientApp/srcフォルダー(P001ReactPlain)

 最初に実行されるのがindex.jsで、それが内部的にApp.jsに定義されたAppコンポーネントをWebページに表示します。srcフォルダー内ファイルの役割を表1に示します。今回は、プロキシーを設定するsetupProxy.js(後述)以外は変更せずそのまま利用します。

表1 srcフォルダーに含まれるファイル(P001ReactPlain)
No. ファイル名 役割
1 App.js Webページに表示する最上位のコンポーネント
2 App.test.js App.jsの単体テストファイル
3 custom.css
デフォルトのCSSファイル
4 index.js 最初に実行されて、App.jsのコンポーネントを画面に
表示する処理
5 reportWebVitals.js Webページの計測を行うWeb Vitalsのファイル
6 service-worker.js
Webページと独立して動作するService Workerのファイル
7 ServiceWorkerRegistration.js Service Workerを登録する処理のファイル
8 setupProxy.js プロキシーを設定する処理のファイル

 Webページの表示内容に対応する実装(コンポーネント)は、Clientapp/src/componentsフォルダー内に存在します(図7)。

図7 ReactプロジェクトのP001ReactPlain/ClientApp/src/componentsフォルダー(P001ReactPlain)
図7 ReactプロジェクトのP001ReactPlain/ClientApp/src/componentsフォルダー(P001ReactPlain)

 componentsフォルダー内各ファイルの役割を表2に示します。Layout.jsがページ全体に対応し、その中にNavMenu.jsによる画面上部メニューが表示されます。画面上部メニューの「Home」「Counter」「Fetch data」リンクをクリックすると、各リンクに対応するHome.js、Counter.js、FetchData.jsのコンポーネントを切り替え表示できます。

表2 componentsフォルダーに含まれるファイル(P001ReactPlain)
No. ファイル名 役割
1 Counter.js Counterページに対応するコンポーネントファイル
2 FetchData.js Fetch dataページに対応するコンポーネントファイル
3 Home.js
Homeページに対応するコンポーネントファイル
4 Layout.js ページ全体の表示に対応するコンポーネントファイル
5 NavMenu.css 画面上部メニューのスタイルシート
6 NavMenu.js 画面上部メニューのコンポーネントファイル

 以上を踏まえて、本記事ではcomponentsフォルダーにコンポーネントのファイルを1つ追加して、その中でFlexGridを表示するように実装していきます。

サンプルコードと同じ天気予報をFlexGridで表示

 以下ではFlexGridをReactで表示していきます。図8のサンプルでは、図2で通常の表を利用して表示していた天気予報をFlexGridで表示します。

図8 FlexGridで天気予報を表示するサンプル(P002ReactFlexGrid)
図8 FlexGridで天気予報を表示するサンプル(P002ReactFlexGrid)

 実装方法を以下で説明します。まず、FlexGridのパッケージを追加するため、ClientAppフォルダーでリスト1のコマンドを実行します。「@grapecity/wijmo.react.grid」が、React対応のFlexGridパッケージです。

[リスト1]WijmoのFlexGridパッケージを追加するコマンド
npm install @grapecity/wijmo.react.grid

 次にcomponents配下に、追加するコンポーネントに対応するWijmoFlexGrid.jsを追加して、リスト2の通り実装します。

[リスト2]FlexGridを表示するコンポーネント(P002ReactFlexGrid/P002ReactFlexGrid/ClientApp/src/components/WijmoFlexGrid.js)
import { Component } from 'react';
// WijmoのCSS、FlexGridのコンポーネントをインポート ...(1)
import '@grapecity/wijmo.styles/wijmo.css';
import { FlexGrid, FlexGridColumn } from '@grapecity/wijmo.react.grid';
// FlexGridを表示するコンポーネント ...(2)
export class WijmoFlexGrid extends Component {
  // コンストラクター ...(3)
  constructor(props) {
    super(props);
    // stateの初期値を設定 ...(4)
    this.state = { forecasts: [], loading: true };
  }
  // コンポーネント配置(マウント)時の処理 ...(5)
  componentDidMount() {
    // データを取得 ...(6)
    this.populateWeatherData();
  }
  // コンポーネントを表示する処理 ...(7)
  render() {
    // 表示内容 ...(8)
    let content;
    // ロード中(state.loading == true)の場合 ...(9)
    if (this.state.loading) {
      content = <p><em>Loading...</em></p>
    }
    // ロード完了(state.loading == false)の場合 ...(10)
    else {
      content =
        // FlexGrid:グリッド全体を表す ...(11)
        <FlexGrid itemsSource={this.state.forecasts} isReadOnly={true}>
          {/*FlexGridColumn: グリッドの1列を表す ...(12)*/}
          <FlexGridColumn binding="date" header="日時" width={280} />
          <FlexGridColumn binding="temperatureC" header="温度(摂氏)" width={120} />
          <FlexGridColumn binding="temperatureF" header="温度(華氏)" width={120} />
          <FlexGridColumn binding="summary" header="サマリー"></FlexGridColumn>
        </FlexGrid>
    }
    // 表示内容を返却 ...(13)
    return content;
  }
  // データを取得 ...(14)
  async populateWeatherData() {
    // weatherforecast APIからデータを取得 ...(15)
    const response = await fetch('weatherforecast');
    // 取得データをJSONとして解釈 ...(16)
    const data = await response.json();
    // 取得したデータと、ロード完了(loading = false)をstateに設定 ...(17)
    this.setState({ forecasts: data, loading: false });
  }
}

 リスト2の内容を説明します。(1)でWijmoのCSSやFlexGridのコンポーネントをインポートします。コンポーネントの実装(2)では、まずコンストラクター(3)で、Reactで利用する内部状態(state)を初期設定します(4)。stateには、表示する天気予報の内容forecastsと、ロード中かどうかを表すloadingを含みます。

 (5)のcomponentDidMountは、コンポーネントがページに配置(マウント)された時に実行されるReactのライフサイクルメソッドです。ここでは(6)の通り、後述するデータ取得処理を実行します。

 (7)のrenderは、表示内容を返却すると画面に描画してくれるReactのメソッドです。まず(8)で、表示内容を表す変数contentを用意します。state.loadingを参照して、データがロード中の場合は(9)のロード中表示、ロード完了の場合は(10)のグリッド表示がcontentに代入されて、(13)で返却されます。この処理により、state.loadingが変更された時にReactがロード中とロード完了後の処理を自動的に切り替えます。

 ロード完了後の表示(10)内にFlexGridを記述します。グリッド全体を表す<FlexGrid>コンポーネント(11)内に、グリッドの1列を表す<FlexGridColumn>コンポーネント(12)を列の数だけ配置します。<FlexGridColumn>コンポーネントでは、表示するデータ名をbindingに、ヘッダー文字列をheaderに、列の幅をwidthに、それぞれ指定します。

 (6)で呼び出されるデータ取得メソッドpopulateWeatherData(14)では、ASP.NET Coreで実装されているweatherforecast Web APIからデータを取得(15)後、(16)の処理でデータをJSONとして解釈し、(17)でstateのforecastsにそのデータを設定するとともに、loadingにfalseを設定してロード完了を指定します。

 リスト2のコンポーネントを表示するため、画面上部メニューに対応するNavMenu.jsにリンクを追加します(リスト3)。

[リスト3]画面上部メニューにリンクを追加(P002ReactFlexGrid/P002ReactFlexGrid/ClientApp/src/components/NavMenu.js)
<ul className="navbar-nav flex-grow">
(略)
  <NavItem><!-- 追加 -->
    <NavLink tag={Link} className="text-dark" to="/wijmo-flexgrid">Wijmo FlexGrid</NavLink>
  </NavItem>
</ul>

 さらに、App.jsのrenderメソッド内に定義されているルーティングの設定に、リスト2のコンポーネントに対応した記述を追加します(リスト4)。

[リスト4]ルーティングの設定を追加(P002ReactFlexGrid/P002ReactFlexGrid/ClientApp/src/App.js)
render () {
  return (
    <Layout>
(略)
      <Route path='/wijmo-flexgrid' component={WijmoFlexGrid} /><!-- 追加 -->
    </Layout>
  );
}

 以上の実装により、図8の通り、画面右上に追加されたリンクをクリックして、FlexGridで天気予報を表示するコンポーネントを画面表示できます。

[補足]Wijmoのライセンス設定

 上記の実装だけでは、Wijmoはトライアル版として動作します。正式版にするには、ライセンスキーを設定するリスト5の実装をindex.jsに追加します。

[リスト5]Wijmoのライセンス設定(P002ReactFlexGrid/P002ReactFlexGrid/ClientApp/src/index.js)
// Wijmoのライセンス設定
import * as wjcCore from '@grapecity/wijmo';
wjcCore.setLicenseKey('<ライセンスキー>');

ASP.NET Coreで独自のAPIを作ってFlexGridに表示させる

 図8の例では、Visual Studioが生成した天気予報のWeb APIを表示させてきましたが、以下では独自のAPIを実装してFlexGridで表示させる方法を説明します。図9のサンプルでは、CodeZineのWebページが提供しているRSSをサーバー側Web APIで読み込んでクライアント側に渡し、FlexGridで記事のタイトル・URL・公開日時を表示します。

図9 FlexGridでCodeZineの記事一覧を表示するサンプル(P003ReactFlexGridAPI)
図9 FlexGridでCodeZineの記事一覧を表示するサンプル(P003ReactFlexGridAPI)

 まず、サーバー側でRSSを処理するため、NuGet パッケージ マネージャーでMicrosoft.SyndicationFeed.ReaderWriterパッケージを検索してインストールします。

図10 RSS処理パッケージをインストール(P003ReactFlexGridAPI)
図10 RSS処理パッケージをインストール(P003ReactFlexGridAPI)

 次に、Controllers/RSSFetchController.csファイル(リスト6)を生成して、Web APIの処理を実装します。

[リスト6]RSS取得Web API実装の外枠(P003ReactFlexGridAPI/P003ReactFlexGridAPI/Controllers/RSSFetchController.cs)
[Route("api/[controller]")]
[ApiController]
public class RSSFetchController : ControllerBase
{
    [HttpGet]
    public async Task<List<RSSElem>> GetAsync()
    {
(後述)
    }
}

 クラスに付与した[Route("api/[controller]")]、[ApiController]属性により、「api/RSSFetch」というパスに対応するWeb APIであることを指定します。GetAsyncメソッドに付与された[HttpGet]属性は、HTTP GETでのアクセスで実行される処理であることを表します。GetAsyncメソッドの実装はリスト7の通りです。

[リスト7]RSS取得Web APIの内部処理(P003ReactFlexGridAPI/P003ReactFlexGridAPI/Controllers/RSSFetchController.cs)
(略:HttpClientでCodeZineのRSSを読み込んでXmlReaderを生成)
// RSSを読み込むRssFeedReaderを生成 ...(1)
var feedReader = new RssFeedReader(xmlReader);
var elemList = new List<RSSElem>();
// RSSを読み込み ...(2)
while (await feedReader.Read())
{
    switch (feedReader.ElementType)
    {
        // 読み込んだ項目がRSSのItemだった場合 ...(3)
        case SyndicationElementType.Item:
            // itemの内容を読み込んでRSSElemオブジェクトに代入し、リストに追加
            var item = await feedReader.ReadItem();
            var oneElem = new RSSElem()
            {
                Title = item.Title,
                Link = item.Links.First().Uri.ToString(),
                PubDate = item.Published.LocalDateTime
            };
            elemList.Add(oneElem);
            break;
    }
}
// RSSElemリストを返却(JSONのAPI戻り値が生成される) ...(4)
return elemList;

 CodeZineのRSSをアクセスするHttpClientから、RSSをXMLとして読み込むXmlReaderクラスのオブジェクトxmlReaderを取得する処理の後、(1)でxmlReaderからRSSを読み込むRssFeedReaderを生成します。RSSの各要素をwhileループ(2)で読み込み、その要素タイプ(ElementType)がアイテム(SyndicationElementType.Item)だった場合(3)、そのタイトル、URL、公開日時をRSSElemクラス(クラス実装はサンプルコード参照)のオブジェクトに格納してリストに追加します。

 最後に(4)で、RSSの全アイテムデータが格納されたリストを返却します。この処理で、ASP.NET Coreのフレームワークにより、リスト内容がJSON文字列に変換されてAPIの戻り値として返却されます。

 Web APIの戻り値をFlexGridで画面に表示する処理は、<FlexGridColumn>に指定する列名が異なる程度で、ほぼリスト2と同一です。詳細はサンプルコードを参照してください。

[補足]Reactプロジェクトのプロキシー設定

 Visual Studio 2022のReactプロジェクトを開発環境で実行すると、Reactで実装したWebページをホストするNode.jsのWebサーバーと、Web APIをホストするASP.NET CoreのWebサーバーが同時に動作します。これらのサーバーはオリジン(ホスト名+ポート番号)が異なるため、いわゆる同一オリジンポリシーにより、Node.jsのWebサーバーから取得したWebページがASP.NET CoreのWebサーバーが提供するWeb APIへアクセスできません。

 そのため、Visual Studio 2022のReactプロジェクトでは、Node.jsのWebサーバーがASP.NET CoreのWebサーバーのプロキシーとなって、Web APIへのアクセスを中継する設定が行われます。設定を行うのは表1、No.8のsetupProxy.jsで、中継するURLのパスをファイルに記述します(リスト8)。

[リスト8]プロキシーが中継するWeb APIの設定(P003ReactFlexGridAPI/P003ReactFlexGridAPI/ClientApp/src/setupProxy.js)
const context = [
    "/weatherforecast",
    "/api" // プロキシーが/api配下を中継するように設定 ...(1)
];

 リスト6のWeb APIは「api/RSSFetch」というパスでアクセスされるため、プロキシーが中継対象にするパスを(1)の通り追加する必要があります。(1)の記述により「/api」配下の任意のパスが中継対象となります。

まとめ

 本記事では、Visual Studio 2022のReactテンプレートで生成されたReactのWebページに、グレープシティのUI部品Wijmoに含まれるグリッド部品FlexGridを利用する方法を説明しました。FlexGridは、Reactのコンポーネントとして定義されるため、React本体とシームレスに利用できます。ASP.NET CoreのWeb APIと組み合わせる方法も説明しました。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/15643 2022/03/09 12:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング