VB_
VB_

Reputation: 45692

How to move subviews lifecycle responsibilities to Marionette

Question How to move subviews lifecycle responsibilities from MyView to Marionette? (see code below)

The problem here is that items array is formed dynamically on the server, and I don't want to iterate through them in MyView. Do I need Marionette.CollectionView?

Code:

I have my-view.hbs template:

{{#each items}}
  <button class="button">name</button>
  <div name="target"/>  <!-- each target div should contain a subview -->
{{/each}}

And view which renders it:

var MyView = Marionette.LayoutView.extend({
  template: Templates['my-view.hbs'],

  render: function() {
    var items = [ //actually they come from server
      {name: 'car'},
      {name: 'bike'},
      {name: 'skiboard'},
    ];
    this.$el.html(
      this.template({ items: items })
    );
    this.renderSubViews();
    return this;
  },
  /**
   * It creates, renders and append subViews manually.
   * TODO: move responsibilities to Marionette
   */
  renderSubViews: function() {
    var self = this;
    self.subViews = [];
    self.$('div[name=target]').each(function(index, subViewContainer) {
      var subView = new SubView();
      self.subViews.add(subView);
      subView.render();
      $(subViewContainer).append(subView.$el);
    });
  }
});

Upvotes: 1

Views: 39

Answers (1)

Evgeniy
Evgeniy

Reputation: 2921

If short, yes, you need Composite or Collection View. Also i recommend you to use Collection instead plain object, it will help you to make easier communication between data (model) and you views:

var ItemModel = Backbone.Model.extend({
        defaults: {
            name: 'unnamed'
        }
    }), 
    ItemsCollection = Backbone.Collection.extend({
        model: ItemModel
    }),

    MyChildView = Marionette.ItemView.extend({
        template: Templates['my-view.hbs']
    }),
    MyView = Marionette.CollectionView.extend({
        childView: MyChildView,
        collection: new ItemsCollection([
            {name: 'car'},
            {name: 'bike'},
            {name: 'skiboard'}
        ])
    });

also your template will be easier:

<button class="button">name</button>
<div name="target"/>

Upvotes: 2

Related Questions