Backbone.jsを使ってみる

導入から、View、Model、Collectionの基本的な部分までを記載します。

# Backbone.jsの導入
npmを使ってインストールします。

```
npm install backbone jquery
```
node_modulesフォルダにbackbone、underscore、jqueryが入っているはず。

# View
Viewは画面描画やイベントのバインド、処理の呼び出しなどを行うコンポーネントだと思っています。
MVCモデルで言うところの、ViewとController的な役割だと思ってます。

※ES6形式で記載しています。

```js:PlayerView.js
class PlayerView extends Backbone.View {
  constructor(args){
    super(args);
  }

  render(){
    this.$el.text('PlayerView');
  }
}

let playerView = new PlayerView({el:'#user'});
playerView.render();
```

```html:index.html
<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="./node_modules/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="./node_modules/underscore/underscore-min.js"></script>
    <script type="text/javascript" src="./node_modules/backbone/backbone-min.js"></script>
    <script type="text/javascript" src="./PlayerView.js" defer></script>
    <title>ばっくぼーんてすと</title>
  </head>
<body>
  <div id="user"></div>
</body>
</html>
```

Backbone.Viewを継承したPlayerViewを作成しています。
PlayerViewのインスタンスを作成する際に、elプロパティにセレクタを指定することによって、ViewにDOMを対応付けることができます。
今回の例では、idがuserとなっているdivタグ内に、PlayerViewという文字列が表示されるはずです。

# Model
Modelはデータ処理を行うコンポーネントです。MVCでいうModelに該当するはずです。

```js:PlayerModel.js
class PlayerModel extends Backbone.Model {
  constructor(lastName, firstName, number) {
    super();
    if (lastName) {
      this.set('lastName', lastName);
    }
    if (firstName) {
      this.set('firstName', firstName);
    }
    if (number) {
      this.set('number', number);
    }
  }

  defaults() {
    return {
      lastName: '緒方',
      firstName: '孝市',
      number: 79
    }
  }

  getName() {
    return this.get('lastName') + ' ' + this.get('firstName');
  }
```
Backbone.Modelを継承したPlayerModelを作成しています。
Modelには、setメソッド、getメソッドがあり、これを用いて値の設定、取得を行います。
今回はコンストラクタで引数がある場合には、それぞれ値を設定するようにしています。
defaultsメソッドを定義すれば、値が設定されていない場合の初期値を定義することができます。
今回の例では、初期値は緒方監督になります。
また、getNameメソッドを作成しています。これは苗字と名前を半角スペース区切りで繋げた文字列を返却してくれます。

```js:PlayerView.js
class PlayerView extends Backbone.View {
  constructor(args) {
    super(args);
  }

  render() {
    let contents = `<div>名前：${this.model.getName()}</div>
    <div>背番号：${this.model.get('number')}</div`;

    this.$el.html(contents);
    return this;
  }
}

let tanaka = new PlayerModel('田中','広輔',2);
let ogata = new PlayerModel();

let tanakaView = new PlayerView({
  el: '#user1',
  model: tanaka
});
let ogataView = new PlayerView({
  el: '#user2',
  model: ogata
});
tanakaView.render();
ogataView.render();
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="./node_modules/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="./node_modules/underscore/underscore-min.js"></script>
    <script type="text/javascript" src="./node_modules/backbone/backbone-min.js"></script>
    <script type="text/javascript" src="./PlayerModel.js" defer></script>
    <script type="text/javascript" src="./PlayerView.js" defer></script>
    <title>ばっくぼーんてすと</title>
  </head>
<body>
  <div id="user1"></div>
  <div id="user2"></div>
</body>
</html>
```
PlayerViewを少し変更して、renderメソッドで自身が保持しているModelの中身をレンダリングするようにします。
インスタンス化する際には、elに加えてmodelも設定します。

今回の例では、idがuser1のdivタグ内に田中広輔が、idがuser2のdivタグ内には緒方監督が表示されるはずです。

# Collection
CollectionはModelを複数保持できるコンポーネントです。配列やList見たいなものだと思っています。

```js:collection.js
class PlayersView extends Backbone.View {
  constructor(args) {
    super(args);
  }

  render() {
    this.collection.each((model) => {
      let playerView = new PlayerView({model: model});
      this.$el.append(playerView.render().el);
    });
  }
}

let tanaka = new PlayerModel('田中', '広輔', 2);
let kikuchi = new PlayerModel('菊池', '涼介', 33);
let maru = new PlayerModel('丸', '佳浩', 9);
let suzuki = new PlayerModel('鈴木', '誠也', 51);
let arai = new PlayerModel('新井', '貴浩', 25);
let matsuyama = new PlayerModel('松山', '竜平', 44);
let abe = new PlayerModel('安部', '友裕', 6);
let aizawa = new PlayerModel('會澤', '翼', 27);
let yabuta = new PlayerModel('薮田', '和樹', 23);
let ogata = new PlayerModel();

let carp = new Backbone.Collection([tanaka, kikuchi, maru, suzuki, arai, matsuyama, abe, aizawa, yabuta, ogata]);

let playersView = new PlayersView({
  el: '#carp',
  collection: carp
});
playersView.render();
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="./node_modules/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="./node_modules/underscore/underscore-min.js"></script>
    <script type="text/javascript" src="./node_modules/backbone/backbone-min.js"></script>
    <script type="text/javascript" src="./PlayerModel.js" defer></script>
    <script type="text/javascript" src="./PlayerView.js" defer></script>
    <script type="text/javascript" src="./PlayersView.js" defer></script>
    <title>ばっくぼーんてすと</title>
  </head>
<body>
  <div id="carp"></div>
</body>
</html>
```

Collectionを描画するPlayersViewを作成しています。
Collection内のPlayerModelを取り出し、PlayerViewで描画した内容を、PlayersViewに追加していく、という処理を行います。
今回の例では、idがcarpのdivタグ内に、カープの選手と監督が描画されるはずです。


----
今回はここまでにして、イベントのバインドなどはいつか記事にしたいと思います。