中安拓也のブログ

プログラミングについて書くブログ

【JavaScript】Ionicで架空のECアプリを作成する #3 - 商品詳細画面を作る

f:id:l08084:20180430174028g:plain

前回の記事はこちら

ハイブリットモバイルアプリフレームワークのIonicを使って、架空のアパレルショップにおける注文アプリを作成する。

第3回目である今回は、商品詳細画面を作成するところまで

  • デモ

こちらのURLで、完成版のアプリを実際に操作することができます

https://l08084.github.io/ionic-sample-shopping-app/www

  • GitHubリポジトリ

github.com

バージョン情報

Angular(JavaScriptのWebフレームワーク)ベースの、ハイブリットモバイルアプリ用フレームワークである「Ionic」を使っている

  • ionic-angular@3.9.2
  • Angular@5.2.10

下準備

商品詳細画面用のファイルを作成

前回作成した商品リスト画面から遷移できる商品詳細画面を作成する。

まず、Ionic CLIの下記コマンドを実行して、必要なファイルのセットを作成する

$ ionic generate page detail --no-module

商品詳細画面のテンプレート、SCSS、コンポーネントファイルが作成される

f:id:l08084:20180430160627p:plain

NgModuleの設定

@NgModuledeclarations: []entryComponents: []配列に先ほど作成した商品詳細画面のクラスDetailPageを追加する。

src/app/app.module.ts

// ...省略

// add this!
import { DetailPage } from "../pages/detail/detail";

@NgModule({
  // add this!
  declarations: [MyApp, AboutPage, ContactPage, HomePage, TabsPage, DetailPage],
  imports: [BrowserModule, IonicModule.forRoot(MyApp), HttpClientModule],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage,
    // add this!
    DetailPage
  ],
// ...省略

実装

商品リスト画面に画面遷移処理を追加

商品リスト画面で商品をタップした時に、商品詳細画面に遷移するようにする。

src/pages/home/home.ts:

// ...省略

// add this!
import { DetailPage } from "../detail/detail";

@Component({
  selector: "page-home",
  templateUrl: "home.html"
})
export class HomePage {
  // ...省略

  constructor(
    // add this!
    private navCtrl: NavController,
    private productProvider: ProductProvider
  ) {}
  
  // add this!
  goToDetail(product: Product) {
    this.navCtrl.push(DetailPage, { product: product });
  }
}

タップした商品を商品詳細画面に渡して遷移するメソッドgoToDetail()を追加した

src/pages/home/home.html:

    // ...省略
 // (click)="goToDetail(jacket)"を追加
    <button ion-item *ngFor="let tops of topsList" (click)="goToDetail(tops)">
      <ion-thumbnail item-start>
        <img src="{{tops.imagePath}}">
      </ion-thumbnail>
      <h2>{{tops.name}}</h2>
      <p>¥{{tops.price}}</p>
    </button>
    <ion-list-header>
      ジャケット/アウター
    </ion-list-header>
    // (click)="goToDetail(jacket)"を追加
    <button ion-item *ngFor="let jacket of jacketList" (click)="goToDetail(jacket)">
      <ion-thumbnail item-start>
        <img src="{{jacket.imagePath}}">
      </ion-thumbnail>
      <h2>{{jacket.name}}</h2>
      <p>¥{{jacket.price}}</p>
    </button>
  </ion-list>
</ion-content>

<button ion-item>(click)="goToDetail(tops)"を追加

商品詳細画面の作成

商品詳細画面の実装をしていく

src/pages/detail/detail.ts:

import { Component } from "@angular/core";
import { NavController, NavParams } from "ionic-angular";
import { Product } from "../../model/product.model";

@Component({
  selector: "page-detail",
  templateUrl: "detail.html"
})
export class DetailPage {
  product: Product;

  constructor(public navCtrl: NavController, public navParams: NavParams) {}

  ngOnInit() {
    this.product = this.navParams.get("product");
  }
}

this.product = this.navParams.get("product");の部分で、商品リスト画面からタップした商品データを受け取っている

src/pages/detail/detail.html:

<ion-header>
  <ion-navbar>
    <ion-title>
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <h2>{{product.name}}</h2>
  <div class="image-container">
    <img class="product-image" src="{{product.imagePath}}">
  </div>
  <div class="comment">
    <p>{{product.commentOne}}</p>
    <p>{{product.commentTwo}}</p>
  </div>
  <ion-list no-lines>
    <ion-item>
      <div>
        <p class="title">小計</p>
        <p class="price">¥{{product.price}}</p>
      </div>
    </ion-item>
    <ion-item></ion-item>
  </ion-list>
  <button ion-button full color="secondary" class="in-cart">カートに1つ追加する</button>
</ion-content>

商品リスト画面から渡された商品データの、名称、値段などを表示している

なお、「カートに1つ追加する」ボタンの処理ついては、今回は書かない

src/pages/detail/detail.scss:

page-detail {
  .image-container {
    display: flex;
    justify-content: center;
  }
  .product-image {
    width: 60%;
    height: 60%;
  }
  .comment {
    margin: 5%;
  }
  .in-cart {
    position: fixed;
    bottom: 60px;
    left: 0;
    margin: 0;
  }
  .title {
    float: left;
    font-weight: bold;
    font-size: 1.7rem;
  }
  .price {
    float: right;
    font-weight: bold;
    font-size: 1.9rem;
    color: #3d9970;
  }
}

画像のサイズが思ったより大きかったので、少し小さくして、flexboxで中央寄せしたりしてる

動作確認

ここまで実装した段階で動作確認をする。

f:id:l08084:20180430172818p:plain
商品詳細画面

ちゃんと商品詳細画面が表示されたので、今回はここまで。


次回の記事