Backbone.jsのRouter/Historyを使ってみる

2013-02-26T00:00:00+00:00 Backbone.js JavaScript

フラグメントハッシュ等を利用した画面転移的な事が出来るらしい。公式ドキュメントだけじゃ微妙だったので

http://qiita.com/items/13f3d1f71d31f3e78123

http://tnakamura.hatenablog.com/entry/20111026/backbone_router

を参考に

概要

ボタンをクリックするとコンテンツを表示、ボタンは複数あって戻る場合もコンテンツ表示処理をRouterで管理する感じ

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css" />
    <script type="text/javascript" src="/static/js/jquery.js"></script>
    <script type="text/javascript" src="/static/js/underscore.js"></script>
    <script type="text/javascript" src="/static/js/backbone.js"></script>
  </head>
  <body>
    <div class="hero-unit">
      <div class="row">
        <!-- ボタン系はこっちにレンダリングする -->
        <div id="header"></div>
      </div>
      <div class="row">
        <!-- コンテンツはこっちにレンダリングする -->
        <div id="content"></div>
      </div>
    </div>
    <script type="text/javascript" src="/index.js"></script>
  </body>
</html>

index.js

var App = {
  "Views": {
    "Header": Backbone.View.extend({
      "el": $("#header"),
      "render": function() {
        this.clear();

        _.each(
          _.range(0, 5), // [0, 1, 2]
          _.bind(
            function(num) {
              // コンストラクタの引数にはmodelを指定した方が良いかと。今回はやってない
              new App.Views.Link({ "num": num + 1 }).render(this.$el);
            },
            this
          )
        );
      },
      "clear": function() {
        this.$el.children().remove();
      }
    }),
    "Link": Backbone.View.extend({
      "tagName": "li",
      "attributes": {
        "style": "float: left; margin: 10px",
        "class": "btn btn-large btn-primary"
      },
      "events": {
        "click": function() {
          // クリックされた際に#entry/:idにtriggerする
          router.navigate("entry/" + this.num, true);
        }
      },
      "initialize": function(param) {
        this.num = param.num;
      },
      "render": function(parentView) {
        parentView.append(
          this.$el.text(this.num)
        )
      }
    }),
    "Page": Backbone.View.extend({
      "el": $("#content"),
      "render": function(id) {
        this.$el.children().remove();

        this.$el.append(
          $("<div>").append(
            $("<h2>").text("ID: " + id)
          )
        );
      }
    })
  }
};

new App.Views.Header().render();

var Router = Backbone.Router.extend({
  "routes": {
    "": "index",
    "entry/:id": "entry"
  },
  /* router.onじゃなくてここに定義しても良いらしい
  index: function() {
    console.log(this);
  }
  */
});

var router = new Router();

router.on("route:index", function() {
  //new App.Views.Header().render();
});

router.on("route:entry", function(id) {
  new App.Views.Page().render(id);
});

// イベント処理のログを出すだけ
router.on("all", function(undefined, route, param) {
  if (!_.isArray(param)) {
    return;
  }

  console.log([route, param]);
});

Backbone.history.start();

ボタンを押す毎にコンテンツが変わる。んで戻るを押していくとコンテンツがそのフラグメントハッシュに応じて変わる。で最終的にはフラグメントハッシュが無い状態まで戻る(但し戻ってもコンテンツは消えない。そういう処理を行なっていない為)

んでもって本日の調査時のツイート

んまぁ大体こんな感じかなーっとpushStateに関しては若干微妙な所が多くてやってない

Android DreamServiceのsettingsActivity Backbone.Viewに突っ込んでみる