SPAプロジェクトにページを追加しよう
では、実際にアプリケーションにページを追加してみましょう。SPAのプロジェクトテンプレートから作成したアプリケーションには、「Weather forecast」という天気予報のページ(メニュー上は「Fetch data」)があらかじめ実装されています。これはサーバ側で生成したランダムな気象情報を表示するページなので、ここでは実際の気象情報を取得できるAPIからデータを取得して表示するページを追加していきます。
本サンプルでは気象情報のAPIにWeather Hacksの「お天気Webサービス」を使用します。
APIの追加
まずはサーバ側にコントローラを追加します。このコントローラではWeather Hacksのお天気Webサービスにアクセスして天気予報データを取得し、クライアント側で必要な内容のみにするため、データを加工します。
・・・中略
[Route("api/[controller]")]
public class WeatherController : Controller
{
[HttpGet("[action]")]
public async Task<IEnumerable<Weather>> Forecasts()
{
// Weather Hacks APIから東京(city=130010)の天気予報を取得
var response = await new HttpClient().GetStringAsync("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010");
var jObject = JObject.Parse(response);
// 取得した情報から必要なデータ(日付・天気)のみ抽出して返却
return jObject["forecasts"]
.Select(forecast => new Weather
{
Date = forecast["date"].ToString(),
Telop = forecast["telop"].ToString()
})
.ToList();
}
public class Weather
{
public string Date { get; set; }
public string Telop { get; set; }
}
}
サーバ側の実装は以上です。以降、このコントローラからデータを取得して画面に表示するクライアント側の実装に入ります。
コンポーネントの追加
新しく追加するページに表示する気象情報データをサーバ側から取得するため、Angularのコンポーネントを作成します。
コンポーネントのディレクトリ(ClientApp/app/components)に新たに/weatherディレクトリを作成し、その中に「weather.component.ts」を作成します。
import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';
@Component({
selector: 'weather',
templateUrl: './weather.component.html'
})
export class WeatherComponent {
// ビュー連携用のフィールド
weathers: Weather[];
constructor(private http: Http, @Inject('BASE_URL') baseUrl: string) {
// サーバからデータを非同期で取得してフィールドにセットする
this.http.get(baseUrl + 'api/weather/forecasts').subscribe(result => {
this.weathers = result.json() as Weather[];
});
}
}
interface Weather {
date: string,
telop: string
}
Angularの提供するnpmパッケージ(@angular/http)を使い、先ほど作成したコントローラ(WeatherController)から天気予報データを取得し、コンポーネントのフィールドにセットしています。これによって次に作成するページへデータを受け渡すことができるようになります。なおコンポーネントにひも付くページは、@Componentデコレータの「templateUrl」で指定しています。
[コラム]Angularのhttpについて
Angularのバージョン4.3以降では、Httpモジュールが刷新され、新たなHttpClientモジュール(@angular/common/http)の使用が推奨されています。
2017年12月現在、.NET Coreのプロジェクトテンプレートから作成されるAngularプロジェクトはバージョン4.2系となっているため、本記事ではHttpモジュールについてもバージョン4.2系に対応したモジュール(@angular/http)を用いて説明をしています。
バージョン4.3以降で使用できるHttpClientモジュールの使用方法については、Angularのサイトを参考にしてください。
ページの追加
APIから取得した天気予報を表示するページをHTMLで作成します。WeatherComponentコンポーネントと同じディレクトリ(ClientApp/app/components/weather)に「weather.component.html」を作成します。
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
<table class='table'>
<thead>
<tr>
<th>Date</th>
<th>Weather</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let weather of weathers">
<td>{{ weather.date }}</td>
<td>{{ weather.telop }}</td>
</tr>
</tbody>
</table>
APIからは数日分のデータが取得できるため、AngularのngFor構文を使って数日分のデータをテーブルに表示できるように実装しています。
AppModuleSharedモジュールへのコンポーネントの追加、ルーティングの追加
コンポーネントとページのセットが実装できたら、それらをAppModuleSharedモジュールに追加します。
import { WeatherComponent } from "./components/weather/weather.component"; //・・・追加
@NgModule({
declarations: [
...中略...
WeatherComponent //・・・追加
],
imports: [
CommonModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
...中略...
{ path: 'weather', component: WeatherComponent }, //・・・追加
{ path: '**', redirectTo: 'home' }
])
]
})
ルーティング先のパス名は「weather」とします。ここで定義したパスを次に説明するナビゲーションページで使用することになります。
ナビゲーションページへのリンクの追加
ブラウザ左側に表示されるナビゲーションページに天気予報のページへのリンクを追加します。
<div class='navbar-collapse collapse'>
...中略...
<!-- 以下のliタグを追加 -->
<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/weather']">
<span class='glyphicon glyphicon-th-list'></span> Wether data
</a>
</li>
</ul>
</div>
</div>
</div>
リンクの一覧の最下部にリンクを追加しました。aタグのrouterLink属性の値に、先ほどルーターへ登録したパス(/weather)を指定しています。
アプリケーションの起動
ここまで実装したらアプリケーションを起動します。「dotnet run」でアプリケーションを起動し、「http://localhost:5000/weather」にアクセスしてください。図2のように数日分の天気が表示されれば成功です。
なお、事前にASPNETCORE_Environment環境変数に開発用の値(Development)を設定してから「dotnet run」コマンドを実行することで、Webpack dev middlewareとHot Module Replacementが有効となります。これによりアプリケーションを起動したままの状態でコードを修正すると、ブラウザの再更新なしで変更が画面に反映されます。
# Windowsの場合 SET ASPNETCORE_Environment=Development # macOS, Linuxの場合 export ASPNETCORE_Environment=Development # アプリケーションの起動 dotnet run
おわりに
フロントエンド開発、SPAフレームワークはトレンドの移り変わりが非常に早い世界です。前回と今回に渡って紹介したJavaScriptServicesを使うことで、流行を取り入れたいクライアントサイドと、安定したサービスを提供したいサーバサイドの利害を一致させつつも異なる技術要素を用いることができ、アプリケーションを疎結合に保つことができることが分かったかと思います。
次回は、ASP.NET Core 2.0と同時に発表されたEntityFramework Core 2.0について紹介します。
