Reputation: 1495
I'm running into a problem getting Backbone.Marionette to cooperate with Twitter Bootstrap. Bootstrap expects markup to conform to predefined patterns in order to work, but the way that Backbone and Marionette handle things, it seems to be impossible to use a Marionette.Layout
to generate Bootstrap-compliant markup for a navbar with an embedded dropdown.
Here's the problem:
Let's say I have a Marionette.Layout
representing the navbar, and I want to have a region
, where I will put the CollectionView
or CompositeView
that manages the items in the dropdown. The region
is a selector, so in this case if we have:
<div class="navbar">
<ul class="nav">
<li>Static item</li>
<li id="dynamic-dropdown"></li>
</ul>
</div>
Then the Layout would specify the region for the dynamic dropdown as follows:
Marionette.Layout.extend({
regions: {
dropdown: '#dynamic-dropdown'
}
...
});
I would then have a CompositeView
that takes care of rendering the dropdown item models, specifies the extra markup for the Bootstrap dropdown, and so forth. The problem is that it appears to be impossible to make #dynamic-dropdown
be the $el
for the CompositeView
, as Backbone always inserts an extra div
(or whatever you specify in tagName
). In order for the dropdown to appear as expected, I need to get rid of that extra element and have the view's root be #dynamic-dropdown
.
I've put together a jsfiddle illustrating what I mean.
tl;dr How do I make a View
's root element be the region specified in a Marionette.Layout
?
Upvotes: 0
Views: 2414
Reputation: 7708
You just need to make sure that the markup that is generated in the end follows the same as required by Bootstrap (use the console to debug).
The required markup is as follows:
The markup generated by your code has the following problems:
So, to fix it you have to change your nav
template to:
<script type="text/html" id="nav">
<div class="navbar">
<ul class="nav" id="dropdown">
</ul>
</div>
</script>
And your views to render <li>
instead of <div>
var DropdownItem = Marionette.ItemView.extend({
tagName: 'li',
template: "#dropdown-item"
});
var DropdownView = Marionette.CompositeView.extend({
template: "#dropdown-collection",
className: 'dropdown',
tagName: 'li',
itemView: DropdownItem,
itemViewContainer: '#dropdown-items'
});
Here is the working version: http://jsfiddle.net/7auhR/6/
Upvotes: 4