I'm trying to get the click
event to fire, but it's not working. Maybe someone can see something I can't.
ConnectionView = GlobalView.extend({
tagName: 'div',
events: {
"click .social-links": "check"
},
initialize: function() {
this.render();
this.model.bind("change", this.render);
},
render: function() {
// Compile the template using underscore
var template = _.template($("#connection-template").html(), this.model.toJSON());
// Load the compiled HTML into the Backbone "el"
$(this.el).html(template);
},
check: function(e) {
e.preventDefault();
alert("woot");
}
});
Here is the template that it's pulling:
<script id="connection-template" type="text/template">
<a id="link-<%= alt %>" class="social-links" href="<%= url.replace('||state||', state).replace('||timestamp||', time) %>">add <%= name %></a>
</script>
Here is the view that puts the ConnectionView into the DOM:
ConnectionsView = GlobalView.extend({
tagName: 'div',
initialize: function(){
this.collection.bind("reset", this.render, this);
},
render: function(){
var $connections = $("<div class='external-accounts'>");
this.collection.each(function (model) {
var conn = new ConnectionView({model: model});
$connections.append(conn.el);
});
// Compile the template using underscore
var template = _.template($("#connections-template").html());
// Load the compiled HTML into the Backbone "el"
$(this.el).html(template({
connectionsList: $connections.outer()
}));
},
destroy: function() {
this.constructor.__super__.destroy.apply(this);
}
});
Your problem is how you're filling in your ConnectionsView
's el
. You're doing this:
// Load the compiled HTML into the Backbone "el"
$(this.el).html(template({
connectionsList: $connections.outer()
}));
I have no idea what .outer()
is all about but it doesn't matter that much. The important thing is that everything is going through the compiled Underscore template()
function and that means that everything will end up getting converted to strings along the way into the page. Once your DOM elements in $connections
are in a string, the event bindings are lost and nothing works anymore.
Consider this example:
http://jsfiddle.net/ambiguous/4tjTm/
In there we do this:
var $connections = $('<div>');
var conn = new ConnectionView({ model: m });
$connections.append(conn.el);
var template = _.template('<%= connectionsList %>');
$('#view-goes-here').append(template({
connectionsList: $connections.html()
}));
to add your ConnectionView
to the page. The events don't work in there because template()
returns a string and that string gets parsed into DOM elements which end up in the page. But, if we add the $connections
straight to the page:
http://jsfiddle.net/ambiguous/AKkCJ/
using something like this:
var $connections = $('<div>');
var conn = new ConnectionView({ model: m });
$connections.append(conn.el);
$('#view-goes-here').append($connections);
the events work as expected.
So now we know what went wrong. But how do we fix it? All we need to do is adjust your ConnectionsView
to add $connections
directly to the DOM with something like this:
render: function() {
// Move <div class='external-accounts'> into your #connections-template.
var template = _.template($("#connections-template").html());
this.$el.html(template());
var $external = this.$el.find('.external-accounts');
this.collection.each(function (model) {
var conn = new ConnectionView({model: model});
$external.append(conn.el);
});
return this; // This is conventional
}
Push the <div class="external-accounts">
into the ConnectionsView
template and insert the ConnectionView
s directly into it. This way you're always working with DOM elements, strings don't know about events but DOM elements do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With