Reputation: 1871
I'm a noob in backbone.js and JavaScript for that matter... and I'm trying to build a simple widget system with Jquery and backbone.js, but I can't seem to figure out how to get multiple instances of my view to render. I am, however able to get one instance to render... my ultimate goal is to build a system where i can click on a button and have it render a new widget on the screen each time. here is my code:
<script type="text/template" id="widget-template">
<div class="widget-wrap">
<div class="widget-header">
<span class="widget-title"><%= widgetInfo.get('title') %></span>
<span class="widget-close"></span>
<span class="widget-hide"></span>
<span class="widget-expand"></span>
</div>
<div class="widget-container">
<!-- this is where the widget content goes -->
</div>
</div>
</script>
<script typ="text/javascript">
var baseWidget = Backbone.Model.extend({
defaults: {
title: "Base",
author: "AB",
multipleInstances: false,
description: "This is the base widget",
pathToIcon: "",
state: "Open",
position: {left:0, top:0}
}
});
var widgetCollection = Backbone.Collection.extend({
model: baseWidget
});
var widgetcol = new widgetCollection();
var baseView = Backbone.View.extend({
el: '.wraper',
render: function(pos = {left:0, top:0}) {
var widget = new baseWidget();
widgetcol.add(widget);
console.log(widgetcol.length);
widget.set({'position':pos})
var template = _.template($('#widget-template').html(), {widgetInfo: widget});
this.$el.html(template);
this.$el.offset({top:widget.get('position').top, left:widget.get('position').left})
$('.widget-wrap').draggable({
handle: ".widget-header",
stop: function (event, ui) {
widget.set({position: ui.position});
console.log(widget.get('position'));
}
});
}
});
BV = new baseView();
BV.render({left:0, top:0});
b = new baseView();
b.render({left:500, top:0});
any help would be greatly appreciated, also if I'm doing anything really strangely I would love advice on how to do it better.
Upvotes: 0
Views: 86
Reputation: 18949
When you are setting the el
property in a view, youre binding the view to an existing element in the dom, limiting yourself to create only one widget. What you actually want to do is let the view generate the element markup and just append all the generated widgets to a certain parent.
You can do that by setting the tagName
, className
and id
attributes in the view.
For example:
var baseView = Backbone.View.extend({
tagName: 'div',
className: '.wrapper'
...
});
That will generate a div
with a class of wrapper
that you can append to a container.
Later on, you define a click event to create a new widget each time:
$('button').click(function() {
var newView = new baseView();
newView.render();
$('.container').append(newView.el); // now 'el' correspond to the div.wrapper you just created
});
It is considered a good practice among backbone developers to return this
from the view's render method. That way you could mix the last two lines like this:
$('.container').append(newView.render().el);
Also, instead if instanciating the collection before the view's definition, people tend to pass the collection as a property of the constructor parameter:
var collection = new widgetCollection();
BV = new baseView({ collection: collection });
Now you can reference the collection inside the view by simply this.collection
.
Upvotes: 3