I’m rather new to Backbone.js development, and have run into a bit of a roadblock while attempting to render a subview.
Currently, I have in place several views to render a custom dropdown-button, as well as other elements. I’ve taken this approach based on DocumentCloud’s code
Here’s what I have so far:
app.ui.SelectMenu = Backbone.View.extend({
className: 'btn-group group-item',
options: {
id: null,
standalone: false
},
events: {
"click .dropdown-menu a": "setLabel"
},
constructor: function (options) {
Backbone.View.call(this, options);
this.items = [];
this.content = JST['common-select_button'];
this.itemsContainer = $('.dropdown-menu', $(this.content.render()));
// Add any items that we may have added to the object params
if (options.items) {
this.addItems(options.items);
}
},
render: function () {
this.$el.html(this.content.render({
label: this.options.label,
items: this.itemsContainer
}));
this._label = this.$('.menu-label');
return this;
},
setLabel: function (label) {
$(this._label).text(label || this.options.label);
},
addItems: function (items) {
this.items = this.items.concat(items);
var elements = _(items).map(_.bind(function (item) {
var attrs = item.attrs || {};
_.extend(attrs, { 'class': 'menu_item' + (attrs['class'] || '') });
var el = this.make('li', attrs, item.title);
return el;
}, this));
$(this.itemsContainer).append(elements);
}
});
So far I have successfully rendered my button, as well as the appropriate label, but I cannot seem to populate the .dropdown-menu when calling the addItems function.
I’m assuming that when render hits, the items variable cannot be populated due to the fact that I am passing a jQuery object and not a string, yet whenever I use items: this.itemsContainer.html(), that simply pastes the html surrounded by quotes… I could simply replace the quotes but that just feels like a hack to me.
Any help would be much appreciated. Thanks!
jQuery’s
appenddoesn’t take an array:If you want to append multiple elements in one call, you have to supply them as separate arguments:
so you’d have to use
applyto convert your array to separate arguments:That sort of chicanery really isn’t necessary though, you can add them one by one as you create them:
Also note that
_.eachcan take acontextargument so you don’t need a separate_.bindcall. And I’m pretty sure thatthis.itemsContaineris already a jQuery object so you don’t need to wrap it$()again.You might have problems with your
renderas well:I suspect that
items: this.itemsContaineris going to end stringifyingthis.itemsContainer, you might have better luck with something like this:where
'some selector'would, of course, depend on the HTML structure; you’ll have to adjust the template for this as well.Your Github link is broken so I don’t know what code you’re adapting. I do know that your use of
constructoris non-standard. Why not use the standardinitialize?You should probably do it this way: