I'd like to ask for some help because I've been trying to solve this for some time now. I've read Derick Bailey's blog post on tree structures and CompositeViews. I also read David Sulc's but I have what I think is a slightly different use case than the one described there. Note: My project uses Marionette.js 1.0.3.
I am trying to build something that will work like an inbox with emails displayed in a table. An email may be a thread, meaning that it will have other emails that are linked to it. The inbox view is being rendered in a <table>
where each <tr>
is an email. My JSON looks like:
[
{id: 1, subject: 'One', threads: []},
{id: 2, subject: 'Two', threads: [
{id: 3, subject: 'Three', threads: []},
{id: 4, subject: 'Four', threads: []}
]},
{id: 5, subject: 'Five', threads: []}
]
My views are configured like this:
InboxView = Marionette.CompositeView.extend({
// edited for brevity
initialize: function(options) {
this.itemView = EmailView;
}
// edited for brevity
});
EmailView = Marionette.CompositeView.extend({
// edited for brevity
tagName: 'tr',
initialize: function(options) {
this.collection = this.model.get('threads');
},
onRender: function() {
if (this.model.isThread()) this.$el.addClass('thread');
}
// edited for brevity
});
The issue I'm having is that if I let CompositeView work its magic for me by rendering the model once and then the collection of threads once, I end up with two table rows <tr>
(one for each thread) inside the <tr>
for the original email (parent).
There exists functionality in the InboxView
and EmailView
that I'm trying to reuse. What I'm trying to end up with is a table that has all rows shown at the same level.
If you're reading this and want to help me, thank you in advance!
First of all you should attach views to the DOM. Errors occur, because child views rendered before they are attached to the DOM. You can override some methods to solve the problem. That will do the trick:
JSFiddle: http://jsfiddle.net/d1krtxtr/