Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show CompositeView with multiple children view in Backbone Marionette

The Starting Problem

I have a CompositeView (a table) for which each model in the collection is represented as two table rows, with a template like:

<tr class="row-parent">
    <td>parent info here</td>
</tr>
<tr class="row-child">
    <td>child info here</td>
</tr>

With an ItemView like this:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl
});

Even though they are named 'parent' and 'child', they are actually peer members of the same model. If I don't specify a tagName, Backbone will wrap each view in a <div> which is both invalid HTML and also breaks the layout.

The First Attempt at a Solution

So I figured, why not remove the outer <tr> tags and let Backbone add them in. So I updated my template to be like:

    <td>parent info here</td>
</tr>
<tr class="row-child">
    <td>child info here</td>

And updated the view to:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl,
    tagName: 'tr',
    className: 'row-parent'
});

I was hoping that an outer tag would combine with the inner tag fragments, but Marionette didn't like that. It only showed the row-child. So I'm not sure where to go from here. I'm considering two strategies but haven't gone into much details yet.

Moving Forward: Plan A

Override whatever part of Backbone creates the extra div to not create it, or override the part of Marionette which appends the view to remove the div just before appending.

Moving Forward: Plan B

Create a new type of view called CompositeMultiView which, naturally, would extend off CompositeView and allow you two specify a second ItemView, or maybe just an array of views, all of which would be rendered for each model given. This plan seems like a lot more work but less hacked.


Does anyone have any better suggestions, workarounds or concrete pointers as to how I would go about implementing either of the two above plans?

Here is a mockup of what the table should look like: enter image description here

like image 800
T Nguyen Avatar asked Sep 08 '13 22:09

T Nguyen


1 Answers

I struggled with that same problem until I finally discovered today, that a table can have multiple tbody tags, each one containing multiple tr tags.

This is actually the answer provided to a similar backbone question.

So your ItemView would become:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl,
    tagName: 'tbody'
});

And the generated html:

<table>
  <!-- first item -->
  <tbody>
    <tr class="row-parent">
      <td>parent info here</td>
    </tr>
    <tr class="row-child">
      <td>child info here</td>
    </tr>
  </tbody>
  <!-- second item -->
  <tbody>
    <tr class="row-parent">
      <td>parent info here</td>
    </tr>
    <tr class="row-child">
      <td>child info here</td>
    </tr>
  </tbody>
  ...
</table>
like image 95
patatepartie Avatar answered Oct 31 '22 14:10

patatepartie