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回

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

サンプルコードと同じ天気予報を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と組み合わせる方法も説明しました。

関連リンク

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

  • このエントリーをはてなブックマークに追加
最先端テクノロジーに対応した高速・軽量なJavaScript UIライブラリ「Wijmo」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLDB/PEAR/Smarty)」「独習シリーズ(ASP.NET/PHP)」「10日でおぼえる入門教室シリーズ(ASP.NET/PHP/Jakarta/JSP&サーブレット/XML)」「Pocket詳解辞典シリーズ(ASP.NET/PHP/Perl&CGI)」「今日からつかえるシリーズ(PHP/JSP&サーブレット/XML/ASP)」「書き込み式 SQLのドリル」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング