実践入門 Ember.js

第6回 実践:ショッピングカート②(Ember.Object, Observer)

この記事を読むのに必要な時間:およそ 7 分

前回はショッピングカートを作成を通じて,Ember.jsの汎用的な機能を解説しました。 今回は前回作成したショッピングカートを拡張しつつ,さらに他のEmber.jsの機能を紹介します。

今回取り扱うEmber.jsアプリケーションはこちらです。

前回からの差分は次のとおりです。

  • カートの中身が保存される
  • 注文画面で商品の個数を変更できる
  • 注文を確定できる

前準備

さて,さっそくショッピングカートを拡張して……と進みたいところですが,まずは少しだけ準備をしてから進むことにしましょう。実はつい先日の2月7日にEmber.js 1.10.0がリリースされました。

このバージョンからテンプレート記述言語がHandlebarsからHTMLBarsに変更になりました。HTMLBarsはHnadlebarsを元にEmber.jsのために実装されたテンプレート記述言語で,より柔軟な記述とパフォーマンス改善を目的としています。とは言っても,まったく新しい文法になるわけではありません。Handlebarsの機能に追加して,今後段階的に新しい機能が追加されていく予定です。

詳しい変更点とEmber.js 1.9.1からのアップデート手順はEmber.js 1.10.0のリリースノートで解説されています。

本稿でもこの手順にしたがってEmber.js 1.10.0にアップデートすることにしましょう。

ということで,本稿の対象バージョンはこちらです。

Ember.js のバージョンアップ

特に重要な点は次の2つです。

handlebars.jsの代わりにember-template-compiler.jsを読み込む

今までhandlebars.jsをscriptタグで読み込んで利用していましたが,Ember.js 1.10.0からはHTMLBarsを同梱したember-template-compiler.jsを利用します※1)⁠

ember.jsの代わりにember.debug.jsを読み込む

開発用のデバッグ出力機能が充実したember.debug.jsと,本番用にデバッグ処理をなくしてパフォーマンスを向上させたember.prod.jsがあります。Ember.js 1.9.1まで開発用のファイル名はember.jsだったのですが,開発用・本番用の区別をしやすくするために名前が変更されました。

※1
ember-cliEmber Railsといったビルドツールを利用すると,HTMLBarsのテンプレートをJavaScriptのコードにコンパイルできます。あらかじめコンパイルしたテンプレートを利用すると初描画時のパフォーマンスが向上します。コンパイル済みのテンプレートを利用する場合,ember-template-compiler.jsを読み込む必要はありません。これらのビルドツールについては,今後の連載で解説します。

さて,これらを踏まえて準備しましょう。第5回で作成したアプリケーションを次のように変更します。

  1. まずは,必要なファイルをダウンロードしてlibsディレクトリに保存します。
  • jquery-2.1.3.min.js2.1.3
  • ember.debug.js1.10.0
  • ember-template-compiler1.10.0
  1. index.htmlのscriptタグを以下のように記述します。

    <script src="libs/jquery-2.1.3.js"></script>
    <script src="libs/ember-template-compiler.js"></script>
    <script src="libs/ember.debug.js"></script>

以上で準備完了です。では,さっそくショッピングカートに機能を追加していきましょう。

カートの保存

ここまでのショッピングカートだとブラウザをリロードするとカートの中身が失われてしまっていました。これでは安心して買い物ができません。そこでカートの中身をlocalStorageに保存することで,ブラウザをリロードしてもカートの中身が失われないようにします。

方針は次のとおりです。

  1. 商品をカートに入れたタイミングで商品IDをlocalStorageに保存する
  2. 画面を表示したタイミングでlocalStorageから商品のIDを読み出しカートの中身を復元する

商品IDを保存する

まずはCartControllerにカートの中身を保存するメソッドを追加します。

App.CartController = Ember.ArrayController.extend({
  // ...

  save: function() {
    var ids = JSON.stringify(this.mapBy('id'));

    localStorage.setItem('cart-product-ids', ids);
  }
}

localStorageに保存できる値は文字列のみなので,JSON.stringify()しているのがポイントです。

続いて,ProductsRouteaddCartアクションでsave()メソッドを呼びます。

App.ProductsRoute = Ember.Route.extend({
  // ...

  actions: {
    addCart: function(product) {
      this.controllerFor('cart').pushObject(product);
      this.controllerFor('cart').save();

      this.transitionTo('cart');
    }
  }
}

これでカートに追加した商品のIDをlocalStorageに保存できるようになりました。まだカートの内容を復元する処理を入れていないので画面からの確認はできませんが,開発者コンソールからであれば確認できます。

いくつかの商品をカートに入れた状態で次のコードをコンソールに打ち込んでみてください。

localStorage.getItem('cart-product-ids');

選択した商品のIDが表示されたでしょうか?

さて,ここまでで商品IDを保存できるようになりましたが,このIDから商品を辿るにはどうすればよいでしょうか? 商品一覧はProductsRouteの中にだけ存在しているので,今のままではCartControllerから商品一覧を取得できません。

そこで,商品管理の仕組みを整理して必要に応じて参照できるようにしておきましょう。Ember.ObjectというEmber.jsが提供するクラスの仕組みを利用して,商品オブジェクトを問い合わせるためのメソッドを持ったクラスを作成することにします※2)⁠

※2
JavaScriptはプロトタイプベース言語であるため,言語としてのJavaScriptに「クラス」という概念はありません。しかしEmber.jsはフレームワークのレベルでクラスを定義しています。

著者プロフィール

佐藤竜之介(さとうりゅうのすけ)

株式会社えにしテック所属。JavaScriptとRubyが好きなウェブ系プログラマ。オープンソースソフトウェアに強い関心がありEmber.jsにも数多くのパッチを送っている。

ブログ:http://tricknotes.hateblo.jp/
Twitter:@tricknotes

コメント

コメントの記入