AngularとSpring Bootで商品一覧画面を作ってみる

はじめに

前回までで、

Spring BootによるRest APIの作成方法、

AngularからRest APIをコールする方法やレスポンシブ対応画面作成方法などを解説しました。

 

今回は、それらのおさらいも兼ねてAngularとSpring Bootで一覧表示系の画面を作成してみようと思います。

まぁこんな画面を作ってみます。(もちろんレスポンシブ対応)

今回作成するサンプルプログラムの動きはこんな感じ

 

 

 環境

  • OS:OS X 10.11 El Capitan
  • STS:3.8.4.RELEASE
  • node:v8.1.0
  • Angular CLI:1.1.1
  • Visual Studio Code:1.13

 

前提

Rest APIは作成済みの前提で説明します。まだの方はこちらを参照ください。

【Spring Boot入門(4)】Rest API(GET)を作ってみる

 

 

一覧表示系画面の作成

では、早速一覧画面の作成に取り掛かりましょう。

以下の手順で作成していきます。

  1. Spring BootのRest API動作確認
  2. Angularで一覧表示系画面作成
  3. Spring Boot、Angular疎通確認

1.Spring BootのRest API動作確認

最初に、作成済みのRest APIの動作確認をしておきましょう。

STSを起動し、パッケージ・エクスプローラーでsrc/main/java/com/example/RestApiApplication.javaを右クリック>実行>Spring Boot アプリケーションでAPサーバを起動します。

 

Google Chromeで「http://localhost:8080/api/items」にアクセスします。

上のようにJSON形式のデータが表示されればOKです。

バックエンドの準備は完了です。

 

2.Angularで一覧表示系画面作成

次はAngularで商品一覧画面を作成します。

作成に必要な作業は以下です。

  • Angular CLIでのプロジェクト新規作成
  • プロジェクトに必要なモジュールインストール
  • app.component.htmlの修正
  • style.cssの修正
  • item.tsの作成
  • item.service.tsの作成
  • dashboard.componentの作成
  • app.module.tsの修正

 

Angular CLIでのプロジェクト新規作成

Visual Stuido Codeを起動し、「Shift」+「Control」+「@」で統合ターミナルを立ち上げます。

 

任意のディレクトリ内で、プロジェクトを新規作成します。

command
$ ng new itemListDisplaySample
以上でプロジェクト作成は完了です。

 

プロジェクトに必要なモジュールインストール

まず、Angular Materialをインストールします。

command
$ npm install --save @angular/cdk
$ npm install --save @angular/material @angular/animations
$ npm install --save hammerjs
次に、Flex Layoutをインストールします。
command
$ npm install https://github.com/angular/flex-layout-builds.git
以上でモジュールのインストールは完了です。

 

app.componentの修正

src/app/app.component.tsを以下のように修正します。

src/app/app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = '商品一覧画面';
}
src/app/app.component.htmlを以下のように修正します。
src/app/app.component.html
<div>
  <h1>
    {{title}}
  </h1>
</div>
<!-- DashboardComponent読み込み -->
<my-dashboard></my-dashboard>

style.cssの修正

src/style.cssを以下のように修正します。

src/style.css
/*テーマ設定*/
@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

 

item.tsの作成

src/app/item.tsを作成します。

src/app/item.ts
export class Item {
    price : number;
    name : String;
    imgPath : String;
}

 

item.service.tsの作成

item.service.ts src/app/services/item.service.tsを作成します。

import { Injectable }    from '@angular/core';
import { Headers, Http, Jsonp, RequestOptionsArgs, RequestOptions, URLSearchParams} from '@angular/http';
import {Observable} from  "rxjs/Observable";
import "rxjs/add/operator/map";

import { Item } from '../item';

@Injectable()
export class ItemService {

  //RestAPIのURL
  private itemsUrl = 'http://localhost:8080/api/items';
  //JSONPコールバック関数名(Angular固有値)
  CALLBACK = 'JSONP_CALLBACK';
  

  //コンストラクタで利用するモジュールをインスタンス化
  constructor(private http: Http, private jsonp: Jsonp) { }


  //商品一覧取得
  getItems(): Observable<Item[]> {
    //リクエストパラメータセット
    let option : RequestOptions;
    option = this.setHttpGetParam(this.itemsUrl);

    //レスポンス返却
    return this.jsonp.request(this.itemsUrl, option)
      .map((response) => {
        let content;
        let obj = response.json();
        content = {
          error: null,
          data: obj
        };
        console.dir(content);
        return content;

      });
               
  }


  //Http(Get)通信のリクエストパラメータをセットする
  private setHttpGetParam(url: string): RequestOptions {
    let param = new URLSearchParams();
    param.set("callback", this.CALLBACK);
    let options: RequestOptionsArgs = {
      method: "get",
      url: url,
      search: param
    };
    return new RequestOptions(options);
  }

}

dashboard.componentの作成

src/app/dashboard/dashboard.component.tsを作成します。

src/app/dashboard/dashboard.component.ts
import {Component, OnInit} from "@angular/core";
import {Item} from "../../item";
import {ItemService} from "../../services/item.service";

@Component({
    selector: 'my-dashboard',
    templateUrl: './dashboard.component.html'
})

export class DashboardComponent implements OnInit{

    //コンポーネント生成時の処理
    constructor(private itemService: ItemService){}

    //商品リスト
    itemList : Item[];

    //画面初期表示イベント処理
    ngOnInit(): void {
        this.itemService.getItems().subscribe(
            result => this.setItems(result),
            error => alert('通信エラー' + error)
        );
    }

    //Web APIから取得したデータを商品リストにセットする
    setItems(result): void {
        if(result.error) {
            alert('Web APIエラー' + result.message);
        }

        this.itemList = result.data;
    }
}

src/app/dashboard/dashboard.component.htmlを作成します。

src/app/dashboard/dashboard.component.html
<md-card>
  <md-card-content>
    <h2 class="example-h2">商品一覧画面コンポーネント</h2>
    <div fxLayoutWrap fxLayoutAlign="space-around center">
      <md-card *ngFor = "let item of itemList" class="example-card" fxFlex="48%" fxFlex.xs="100%">
        <md-card-header>
          <md-card-title>{{item.name}}</md-card-title>
          <md-card-subtitle>これは「{{item.name}}」です</md-card-subtitle>
        </md-card-header>
        <img md-card-image src="http://localhost:8080/{{item.imgPath}}">
        <md-card-content>
          <p>この「{{item.name}}」は{{item.price}}円です。</p>
        </md-card-content>
        <md-card-actions>
          <button md-button>詳細情報</button>
          <button md-button>削除</button>
        </md-card-actions>
      </md-card>
    </div>
  </md-card-content>
</md-card>

8.app.module.tsの修正

src/app/app.module.tsを修正します。

src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule,JsonpModule} from '@angular/http';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import 'hammerjs';
import {MdCheckboxModule,MdRadioModule,MdCardModule,MdInputModule,MdButtonModule} from '@angular/material';
import {FlexLayoutModule} from "@angular/flex-layout";

import { DashboardComponent } from './component/dashboard/dashboard.component';
import { AppComponent } from './app.component';

//商品情報取得用service
import {ItemService} from './services/item.service';

@NgModule({
  declarations: [
    AppComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    JsonpModule,
    BrowserAnimationsModule,
    MdCheckboxModule,
    MdRadioModule,
    MdCardModule,
    MdInputModule,
    MdButtonModule,
    FlexLayoutModule
  ],
  providers: [
    ItemService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

最終的に出来上がるAngularプロジェクトの構成は以下のようになります。

 

 

3.Spring Boot、Angular疎通確認

STSを起動し、パッケージ・エクスプローラーでsrc/main/java/com/example/RestApiApplication.javaを右クリック>実行>Spring Boot アプリケーションでAPサーバを起動します。

 

Visual Stuido Codeを起動し、「Shift」+「Control」+「@」で統合ターミナルを立ち上げます。

カレントディレクトリを作成したプロジェクトへ移します。

command
$ cd itemListDisplaySample
Webサーバを立ち上げます。
command
$ ng serve
Google Chromeで「http://localhost:4200」にアクセスします。

上のように表示されればOKです。

画面を狭めると以下のように表示されるはずです。

 

 

おわりに

手順が長く、、なかなかしんどかったですね。。。

ですが、Angular⇔Spring Bootの連携ができて、レスポンシブな画面が作れました。

 

こんな感じでSPA(Single Page Application)って作られるんじゃないかなぁと思っています。今回やったことが応用できればSPAを新規作成したり既存改修するような現場に放り込まれてもなんとか対応できるかも、

もう少し実践に近いサンプルを、、次は作成してみます!!!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください