Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve deprecated CompositeView functionality in Marionette 3+?

As stated in the latest Marionette docs:

CompositeView is deprecated. You should use the replaceElement option on Region.show and render a CollectionView into a region inside a View to achieve this functionality.

I still can't understand how CompositeView functionality should be achieved now.

Previously, CompositeView was perfect for using with such template:

<script id="table-template" type="text/html">
<table>
  <% if (items.length) { %>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Description</th>
    </tr>
  </thead>
 <% } %>

  <tbody></tbody>

  <tfoot>
    <tr>
      <td colspan="3">some footer information</td>
    </tr>
  </tfoot>
</table>

new MyCompositeView({
  template: "#table-template",
  templateContext: function() {
    return { items: this.collection.toJSON() };
  }
  // ... other options
});

If we decide to use LayoutView instead of CompositeView then we need to code manually a lot of event bindings (for example to show / hide table header based on number of items in collection). This makes things harder.

Are there any clean and not complicated ways to live without CompositeView?


Thank you for any help or advice.

like image 508
James Akwuh Avatar asked Mar 31 '16 19:03

James Akwuh


1 Answers

It looks like Marionette 3 is going to get rid of some concepts to make the framework simpler overall, and easier to understand.

Marionette.View in 3 is going to include functionality from what was ItemView and LayoutView. CompositeView is deprecated in favour of just using RegionManager, which is now included into View.

v2 --> v3
View -> AbstractView  
ItemView, LayoutView -> View

Here's a quick example app:

var color_data = [ { title:'red' }, { title:'green' }, { title:'blue' } ];

var Color = Backbone.Model.extend({
  defaults: { title: '' }
});

var Colors = Backbone.Collection.extend({
  model: Color
});

var ColorView = Mn.View.extend({
  tagName: 'tr',
  template: '#colorTpl'
});

var ColorsView = Mn.CollectionView.extend({
  tagName: 'tbody',
  childView: ColorView
});

var AppView = Mn.View.extend({
  template: '#appTpl',
  templateContext: function(){
    return {
      items: this.collection.toJSON()
    };
  },
  ui: {
    input: '.input'
  },
  regions: {
    list: {
      selector: 'tbody',
      replaceElement: true
    },
  },
  onRender: function(){
    this.getRegion('list').show(new ColorsView({
      collection: this.collection
    }));
  },
  events: {
    'submit form': 'onSubmit'
  },
  onSubmit: function(e){
    e.preventDefault();
    this.collection.add({
      title: this.ui.input.val()
    });
    this.ui.input.val('');
  }
});

var appView = new AppView({
  collection: new Colors(color_data)
});
appView.render().$el.appendTo(document.body);
<script src='http://libjs.surge.sh/jquery2.2.2-underscore1.8.3-backbone1.3.2-radio1.0.4-babysitter0.1.11-marionette3rc1.js'></script>

<script id="colorTpl" type="text/template">
  <td><%=title%></td>
  <td style="background-color:<%=title%>">&nbsp;</td>
</script>

<script id="appTpl" type="text/template">
<table width="100%">
  <% if(items.length) { %>
    <thead>
      <tr>
        <th width="1%">Title</th>
        <th>Color</th>
      </tr>
    </thead>
  <% } %>
  <tbody></tbody>
  <tfoot>
    <tr>
      <td colspan="2">
        <form><input type="text" class="input" autofocus><input type="submit" value="Add Color"></form>
      </td>
    </tr>
  </tfoot>
</table>

  
</script>
like image 190
Yura Avatar answered Sep 18 '22 16:09

Yura