LoginSignup
3
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-02-11

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を指定してあげないと上手くいきませんでした。(これに気付くのに結構ハマった・・・)

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4