Meteor入門 [2] サンプルプロジェクトを読んでみる

Javascriptでクライアントサイドからサーバサイドまでやれちゃう、話題の新技術Meteorを勉強してみる。の記録。
http://www.meteor.com/main

サンプルプロジェクトを動かしてみる。
http://www.meteor.com/examples/leaderboard

インストールは終わってるものとして。
http://d.hatena.ne.jp/shinobu_siv/20120609/1339245562

リーダーボードサンプルプロジェクトを作成

meteor create --example leaderboard

ローカル実行

cd leaderboard
meteor

これで、ローカルホストの3000番( http://localhost:3000/ )にアクセス

プロジェクトを作成するとファイルが3つ作成される。

leaderboard.html
leaderboard.js
leaderboard.css

この内、cssはいいとして、他の2つのファイルについて見てみる。

まずは、leaderboard.htmlから。中身は基本的にHTML。

<head>
  <title>Leaderboard</title>
</head>

<!-- 非常に短いbodyタグ -->
<body>
  <div id="outer">
    {{> leaderboard}} <!-- ここにtemplateタグの内容が挿入されるようだ-->
  </div>
</body>

<!-- leaderboardテンプレートはここから-->
<template name="leaderboard">
  <div class="leaderboard"> 
    <!-- playersの数だけplayerテンプレートを挿入-->
    {{#each players}}
      {{> player}}
    {{/each}}
  </div>

  <!-- selected_name (セッションに格納されている) に値が入っていればボタンを表示-->
  {{#if selected_name}}
  <div class="details">
    <!-- セッションに格納されているselected_nameの値を表示-->
    <div class="name">{{selected_name}}</div>
    <!-- 5ポイント追加ボタン-->
    <input type="button" class="inc" value="Give 5 points" />
  </div>
  {{/if}}

  <!-- selected_name がなければ、クリックして選択するように促す表示-->
  {{#unless selected_name}}
  <div class="none">Click a player to select</div>
  {{/unless}}
</template>

<!-- ここからplayerテンプレート-->
<template name="player">
  <div class="player {{selected}}">
    <span class="name">{{name}}</span>
    <span class="score">{{score}}</span>
  </div>
</template>

次にleaderboard.jsを見てみる。

//プレイヤーの情報を保存するコレクションをセットアップ。
//サーバ側でMongoDBにplayersという名前で保存される
Players = new Meteor.Collection("players");

//Meteor.is_clientでクライアント側であることをチェック
if (Meteor.is_client) {

  //playersコレクションからデータを取り出す関数をleaderboardのplayersフィールドにセット
  Template.leaderboard.players = function () {
      //playersコレクションから全て取り出して、scoreで降順、名前で昇順にソート
      //(コレクションと読んでいいのかな? MongoDBの用語がよくわかってないけれど、、、)
      return Players.find({}, {sort: {score: -1, name: 1}});
  };

  //選択されているplayerをデータベースから取得。
  //プレイヤーが存在し、名前を持っているかどうかを返す
  Template.leaderboard.selected_name = function () {
    var player = Players.findOne(Session.get("selected_player"));
    return player && player.name;
  };

  //選択されているplayerの場合"selected"の値を返す。
  //leaderboard.htmlではdivのclassに挿入される
  Template.player.selected = function () {
    return Session.equals("selected_player", this._id) ? "selected" : '';
  };

  //leaderboardテンプレートのへのクリックイベント設定
  Template.leaderboard.events = {

    //incクラスが指定されたinputタグへのクリックイベント設定
    'click input.inc': function () {
      //クリックしたらセッションのselected_playerのscoreの値を5増やす
      Players.update(Session.get("selected_player"), {$inc: {score: 5}});
    }
  };
   
  //playerテンプレートへのクリックイベント設定
  Template.player.events = {
    'click': function () {
      //クリックしたらセッションにselected_playerの値をセット
      Session.set("selected_player", this._id);
    }
  };
}

//Meteor.is_clientでサーバ側であることをチェック
if (Meteor.is_server) {
  //初期設定
  Meteor.startup(function () {
    //プレイヤーが設定されて無ければ作成
    if (Players.find().count() === 0) {
      var names = ["Ada Lovelace",
                   "Grace Hopper",
                   "Marie Curie",
                   "Carl Friedrich Gauss",
                   "Nikola Tesla",
                   "Claude Shannon"];
      for (var i = 0; i < names.length; i++)
        Players.insert({name: names[i], score: Math.floor(Math.random()*10)*5});
    }
  });
}

ザックリとだが構造がわかってきた。

JavascriptとMongoDBの用語の正しい使い方が解らない、、、