中安拓也のブログ

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

【JavaScript】Ionicで架空のECアプリを作成する #5 - カート画面を作る(後編)

前回の記事はこちら

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

第5回目である今回は、カート画面を作成するところまで

  • デモ

こちらの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
  • Google Chrome バージョン: 60.0.3112.113

実装

カート画面の実装

カート画面の実装をしていく。

  • ポイント
    • 画面の初期表示以外のタイミングでも、ストレージを読み込む必要があるため、ionViewDidLoadではなく、ionViewDidEnterを使う
    • IonicのAlertControllerを使って、確認アラームを表示している
    • 確認アラームのOKを選択すると、注文が完了したことを知らせるアラームが表示される

src/pages/cart/cart.ts:

import { Component } from "@angular/core";
import { AlertController, NavController, Events } from "ionic-angular";
import { Product } from "../../model/product.model";
import { Storage } from "@ionic/storage";
import { ProductProvider } from "../../providers/product/product";

@Component({
  selector: "page-cart",
  templateUrl: "cart.html"
})
export class CartPage {
  // カート内の商品の一覧
  productList: Product[];
  // 小計
  subtotal: number;
  // 合計
  total: number;
  // カート内が空の時にtrue
  isEmpty: boolean;

  constructor(
    public navCtrl: NavController,
    public alertCtrl: AlertController,
    private storage: Storage,
    private productProvider: ProductProvider
  ) {}

  /**
   * Ionicのライフサイクルメソッドの一種
   * ページがアクティブになると呼び出される
   * ストレージ(カート)内に商品が格納されていれば、取得する
   *
   * @memberof CartPage
   */
  ionViewDidEnter() {
    this.productList = [];
    this.subtotal = 0;
    this.total = 0;
    this.isEmpty = false;
    this.storage
      .length()
      .then(result => {
        // カート内に商品がある場合
        if (result > 0) {
          this.storage
            .get("items")
            .then(result => {
              this.productList = result;
              this.productList.forEach(
                // 小計を計算
                product => (this.subtotal += product.price)
              );
              // 小計にデリバリー料を加算して、合計を計算している
              this.total = this.subtotal + 300;
            })
            .catch(err => {});
        } else {
          // カート内が空の場合
          this.isEmpty = true;
        }
      })
      .catch(err => {});
  }

  /**
   * 「注文する」ボタン押下時に呼び出し
   *  Confirm Alertを表示し、OKを選択すると、
   *  注文を確定して、ストレージをクリアする
   *
   * @memberof CartPage
   */
  order() {
    const confirm = this.alertCtrl.create({
      title: "注文を確定しますか?",
      buttons: [
        {
          text: "キャンセル",
          handler: () => {}
        },
        {
          text: "OK",
          handler: () => {
            let alert = this.alertCtrl.create({
              title: "ご注文を受け付けました!",
              subTitle: "ご指定の住所までのお届け時間は、20-30分程です",
              buttons: ["OK"]
            });
            alert.present();
            this.storage.clear();
            this.productList = [];
            this.isEmpty = true;
          }
        }
      ]
    });
    confirm.present();
  }
}
  • ポイント
    • AngularのngIfElseを使っている。ストレージの中身が空の時は、#elseBlock(お客様のショッピングカートに商品はありません。)の方が表示される
    • 注文するボタンを押下すると、order()メソッドを呼び出す

src/pages/cart/cart.html:

<ion-header>
  <ion-navbar>
    <ion-title>
      カート
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <div *ngIf="!isEmpty; else elseBlock">
    <ion-list>
      <ion-item *ngFor="let product of productList">
        <div class="quantity">{{product.quantity}}</div>
        <div class="product">{{product.name}}</div>
        <div class="price">¥{{product.price}}</div>
      </ion-item>
      <ion-item>
        <div class="check-detail">
          <p class="title">小計</p>
          <p class="price">¥{{subtotal}}</p>
        </div>
        <div class="check-detail">
          <p class="title">デリバリー料</p>
          <p class="price">¥300</p>
        </div>
      </ion-item>
      <ion-item>
        <div class="title emphasis">合計(税込み)</div>
        <div class="price emphasis">¥{{total}}</div>
      </ion-item>
      <ion-item no-lines>
      </ion-item>
    </ion-list>
    <button ion-button full color="secondary" class="order" (click)="order()">注文する</button>
  </div>
  <ng-template #elseBlock>
    <h2>お客様のショッピングカートに商品はありません。</h2>
  </ng-template>
</ion-content>
  • ポイント
    • floatの回り込み解除のために、overflow: hidden;を設定している

src/pages/cart/cart.scss:

page-cart {
  .quantity {
    float: left;
    margin: 0 10px 0 0;
  }
  .product {
    float: left;
  }
  .title {
    float: left;
    &.emphasis {
      font-weight: bold;
    }
  }
  .price {
    float: right;
    &.emphasis {
      font-weight: bold;
      color: #3d9970;
      font-size: 1.9rem;
    }
  }
  .check-detail {
    // floatの回り込み解除
    overflow: hidden;
  }
  .order {
    position: fixed;
    bottom: 60px;
    left: 0;
    margin: 0;
  }
}

動作確認

上記のコードを書いた段階で、ionic serveコマンドを実行して、ブラウザ上で確認してみる

カート画面表示

ストレージ(ショッピングカート)内の商品情報がリスト形式で表示されている

f:id:l08084:20180502162652p:plain
カート画面初期表示

注文ボタン押下

「注文する」ボタンを押下すると、Ionicのアラートが表示される

f:id:l08084:20180502163101p:plain
注文ボタン押下時に表示される 確認アラート

f:id:l08084:20180502163019p:plain
確認アラートでOKを選択すると表示されるアラート


次回の記事