シンクロ・フード エンジニアブログ

飲食店ドットコムを運営する、株式会社シンクロ・フードの技術ブログです

IonicとAngularJSを使ってSPAでサービスを作った話

こんにちは、最近CourseraのMachine Learningコースで機械学習を勉強中の安藤です。
今回は食材発注ツール「PlaceOrders」 の開発についてお話したいと思います。
PlaceOrdersの開発ではIonicを使って初めてSingle Page Application(SPA)を構築したので、その感想などを書いていこうと思います。尚、バックエンドはRubyOnRailsです。

f:id:synchro-food:20160908101609p:plain:w300

Ionicとは?

IonicはAngularJSをベースにしたモバイル向けのCSS/JavaScriptフレームワークです。
Apache Cordova(PhoneGap)を利用してネイティブアプリへビルドすることが基本的な使い方ですが、今回はネイティブアプリへのビルドは考えずにスマートフォン/タブレット向けのWEBサイトの開発に使用しました。
http://ionicframework.com/

なぜIonicを採用したか?

当初はPlaceOrdersをネイティブアプリとして開発することも検討していましたが、SPAであればネイティブアプリのようなユーザー体験を提供しながら、Web開発の延長として効率的に開発を進めることができます。
SPAを開発するにあたって検討したフレームワークはIonicとOnsenUIでしたが、Ionicは公式ドキュメントがしっかりしていて、公式フォーラムなどのコミュニティも活発なので情報を探しやすいため初めてSPAを作成する上で安心感がありました。
パフォーマンスでは少し見劣りするといった情報もありましたが、PlaceOrdersでは特別パフォーマンスを重視する必要はなかったため、その点は問題ないと判断しました。

使ってみて良かったところ

ネイティブアプリのような動作が簡単に実現できた

Ionicのコンポーネントを利用するだけでネイティブアプリのように動作を簡単に実現できたことが、今回Ionicを使ってみて一番良かったところです。
画面遷移のアニメーションやサイドメニュー、モーダル、ポップアップなどのコンポーネントを様々な端末、ブラウザに対応して作ろうとするとかなりの労力になりますが、Ionicのコンポーネントはほとんど問題が発生することもなく非常に使いやすかったです。
例えば、ポップアップのコンポーネントでは以下のようにタイトルやテキスト、ボタン名、各ボタンに紐付ける処理などを決まった形で書くだけで利用できます。

var myPopup = $ionicPopup.confirm({
  title: 'myPopup',
  templateUrl: 'myPopup.html',
  buttons: [
    {
      text: 'キャンセル',
      type: 'button-stable',
      onTap: function(e) {
        // キャンセル時の処理
      }
    },
    {
      text: 'OK',
      type: 'button-positive',
      onTap: function(e) {
        // OK時の処理
      }
    }
  ]
});
// ポップアップの表示
myPopup.show();

f:id:synchro-food:20160908101433p:plain:w300

AngularJSベースなので開発しやすかった

IonicはAnglarJSをベースにしているので、通常のAngularJSアプリと同様に開発を進めることができました。
ルーティングには定番モジュールのUI Routerが使用されているため、Nested Viewsでコントローラーやビューの共通化したり、resolveで画面遷移を制御するといった柔軟なルーティングが可能でした。

苦労したところ

大きくハマってしまうことはなかったですが、細かいところで気になるポイントがいくつかありました。

コンテンツサイズ変更時のリサイズ

リストの伸び縮みなどでコンテンツサイズが変化した時に、画面の端までスクロールできなくなることがありました。
サイズが変わるような処理の度に$ionicScrollDelegate.resize()が呼び出されるようにして、強制的にサイズを再計算させることで解決しました。

日本語入力時の挙動

日本語入力時に入力を確定するまでモデルに値が反映されなかったり、確定前に他のテキストボックスにフォーカスを移すと、入力中の文字がフォーカスしたテキストボックスにコピーされてしまうといった現象が一部端末、ブラウザで発生しました。
現在もまだ一部問題が残っていますが、compositionstartというイベントでモデルの更新を止めてしまっている処理を無効化するようなディレクティブを作成したり、data-tap-disabledを付けることで対応しました。
前者の問題については以下の記事が詳しいです。
http://pirosikick.hateblo.jp/entry/2014/10/16/232409

touchstart/touchendイベント

Ionic、AngularJSのどちらにもtouchstart/touchendイベントに対応したディレクティブが実装されていなかっため、独自にディレクティブを作成する必要がありました。
特に難しいものではないですが、なぜ用意されていないのか不思議でした。

最後に

以上、IonicによるSPA開発の所感でした。
初めてのSPA開発でも順調に開発を進めることができたので結果的にはIonicを採用して良かったと思います。

最近ではIonicはAngular2をベースにしたIonic2に移行しつつあるので、機会があればIonic2にも挑戦してみたいと思っています。

尚、シンクロ・フードでは、こういったフロントエンド開発に興味のあるエンジニアを大募集しています!
少しでもご興味があれば、気軽にお話しする場を設けますので、以下よりご連絡ください!

キャリア採用 | シンクロ・フード採用サイト