【Marionette】CompositeViewをCollectionViewで描画するサンプル


1対Nの関連を持つモデルのコレクションをMarionette.jsで表示する際のサンプルです。ちょっとイメージが湧きにくいので例を挙げると、以下のような感じです。

  • クラス
    • 生徒
    • 生徒
    • 生徒
    • ・・・
  • クラス
    • 生徒
    • 生徒
    • 生徒
    • ・・・
  • ・・・

これをCollectionView,CompositeView,ItemViewを使用して描画します。それぞれのビューが対応するモデル,コレクションは以下の通りです。

  • CollectionView : クラスのコレクション
  • CompositeView : クラスモデル、生徒のコレクション
  • ItemView : 生徒モデル

結果的にMariionette.jsなら簡単に描画できました。コード量がそこそこ多くなってますが、ほとんどがモデルの定義・生成部分であり、本質的なのはビューの定義の箇所だけです。

app.js

var Student = Backbone.Model.extend({});

var Students = Backbone.Collection.extend({
  model: Student,
});

var Class = Backbone.Model.extend({});

var Classes = Backbone.Collection.extend({
  model: Class,
});


var StudentView = Marionette.ItemView.extend({
  tagName: 'li',
  template: '#template-student',
});

var ClassView = Marionette.CompositeView.extend({
  template: '#template-class',
  childView: StudentView,
  childViewContainer: 'ul',
});

var ClassListView = Marionette.CollectionView.extend({
  el: '#container',
  childView: ClassView,
  childViewOptions: function(model, index) {
    return {
      model: model,
      collection: model.get('collection'),
      childIndex: index,
    };
  },
});


$(function() {
  var students1 = new Students([
    new Student({ name: 'トム' }),
    new Student({ name: 'マイク' }),
    new Student({ name: 'レベッカ' }),
  ]);
  var students2 = new Students([
    new Student({ name: 'ケン' }),
    new Student({ name: 'ルーシー' }),
  ]);
  var classes = new Classes([
    new Class({ teacher: '山田', collection: students1 }),
    new Class({ teacher: '佐藤', collection: students2 }),
  ]);

  var classListView = new ClassListView({ collection: classes });
  classListView.render();
});

index.html

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="js/underscore.js"></script>
    <script type="text/javascript" src="js/backbone.js"></script>
    <script type="text/javascript" src="js/backbone.marionette.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
  </head>
  <body>
    <div id="container"></div>

    <script id="template-class" type="text/html">
      <p>担任:<%= teacher %></p>
      <ul></ul>
    </script>

    <script id="template-student" type="text/html">
      <%= name %>
    </script>
  </body>
</html>

ポイントはapp.jschildViewOptionsです。単純にCompositeViewを使用する場合は特に難しいことはないのですが、CompositeViewがCollectionViewに描画される場合は、このようにchildViewOptionsで子供ビューに渡すmodel,collectionを指定してあげないと上手くいきませんでした。(これに気付くのに結構ハマった・・・)

関連する記事


コメントする

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください