Backbone.jsでバックエンドとやりとりするスマートデバイス向けアプリを作る(Model編)

3月に入ってからブログがご無沙汰になっていました。
というのは、この1週間ほどいろいろと技術的に新しいことをやっていたのですが、ブログに書くほどの理解が自分の中で進んでいなかったからです。
ようやく、先週末くらいから見えてきたので、そろそろブログにまとめておこうかと思います。

そのやっていたことというのは、スマートデバイス向けのアプリをHTML5で作るということなので、それだけなら、既にこのブログにもいろいろと書いています。HTML5+JavaScript+jQuery MobileでWebアプリを作って、PhoneGapでネイティブアプリっぽい形にする。

先週は、そこからさらに進んで、Ruby on Railsでバックエンド側を作ってHerokuでホストしつつ、クライアント側のHTML5アプリはBackbone.jsを使ってみるということをやっていました。
バックエンドのRailsの方は、実のところscaffoldをやっただけで、これといって何もコーディングとかしていません。なので、Backbone.jsについて書いておこうと思います。

Backbone.jsとは?

backbone

Backbone.jsとは、クライアント側のHTML5+JavaScriptのアプリに適用できるフレームワークです。実際に使ってみて感じたメリットは、

  • JSONでやりとりするバックエンドとの相性の良さ
  • Modelでのidとcidの使い分けの便利さ
  • HTML(View)とロジックの見通しの良さ

という3点です。もっと他にもあるような気がしますが、少し触ったくらいでも、十分なメリットを感じられたのは良かったです。

Backbone.jsを導入する

Backbone.jsの公式サイトはこちら → http://backbonejs.org/

こんな感じで、underscore-min.jsとbackbone-min.jsを読み込みます。

Backbone.jsのModel

Backbone.jsのModelは、JSONでやりとりできるURLを指定しておけば、特に何もコードを書かなくても、サーバからデータを持って来たり、サーバにデータを保存したりすることが出来ます。
Railsはscaffoldを作った段階で、既にJSONでのやりとりが出来るようになっていますので、Backbone.jsとの相性は抜群と言えるでしょう。

もし、こんな感じでRailsのscaffoldを作ったとすると・・・

rails new sample
rails g scaffold user name:string email:string memo:text

Modelの定義は、こんな感じになります。

var User = Backbone.Model.extend({
  urlRoot: "/users"
});

これだけで、Railsで出来たバックエンドとの間で、CRUDが出来てしまいます。

Backbone.jsのCollection

Backbone.jsのModelは、バックエンドの1つのエンティティと紐付いています。複数のエンティティを扱う場合は、Collectionを使います。

var Users = Backbone.Collection.extend({
  model: User,
  url: "/users.json"
});

あとは、こんな感じでアクセスできます。

var users = new Users();
users.fetch({
  error: function() {
    console.log("error");
  },
  success: function(collection, response, options) {
    console.log(collection.length); //取得した件数
    user = collection.get(1); //idが1のユーザを取得
    console.log(user.get("name")); //idが1のユーザのnameを取得
    user = collection.get("c1"); //cidがc1のユーザを取得
  }
});

さて、このコードでのポイントはCIDです。
collection.get(1)のように、getの引数として数値を渡した場合はエンティティのIDと認識され、ModelがCollectionから取得できます。
一方、collection.get(“c1”)のように、cをプリフィックスとするCIDを渡してもModelが取得できます。CIDはBackbone.jsがModelのインスタンスごとにc1から順に独自に採番するIDで、永続化の対象にはなりません。
通常のIDは永続化の際にデータベースで採番させることが多いと思います。つまり、user.save()でBackbone.jsからバックエンドにデータを渡して永続化して初めて採番されるわけですが、CIDの方はModelのインスタンスを作成した時点で(つまり永続化する前に)採番されます。
永続化の前に(テンポラリでも)ユニークなKEYでアクセスできることが便利になるシーンは少なくないのではないかと思います。

エンティティのカラム値の取得は、user.get(“name”)のようにgetメソッドを使います。user.nameのように属性ではないことに注意していください。

Modelの保存

var user = new User();
user.set({
  name: "foo",
  email: "[email protected]",
  memo: "memo memo"
});
user.save(undefined, {
  error: function() {
    console.log("error");
  },
  success: function() {
    console.log("success");
  }
});

Modelインスタンスへのカラム値の設定は、user.set(“name”, “foo”)のように行います(上記のサンプルコードのように連想配列で渡すことも出来ます)。ここでuser.nameのように属性に対して値をセットすることもできますが、その場合は永続化の対象になりません(つまりバックエンドに渡されない)。

saveメソッドの第1引数がundefinedになっていますが、ここで値をセットすることも出来るのです。今回はあらかじめsetメソッドで値をセットしているので、undefinedとしました。

この記事を書いた人

井上 研一

株式会社ビビンコ代表取締役、ITエンジニア/経済産業省推進資格ITコーディネータ。AI・IoTに強いITコーディネータとして活動。画像認識モデルを活用したアプリや、生成AIを業務に組み込むためのサービス「Gen2Go」の開発などを行っている。近著に「使ってわかった AWSのAI」、「ワトソンで体感する人工知能」。日本全国でセミナー・研修講師としての登壇も多数。