1

I'm working on a chat client, and I've come across an issue with Backbone's event system.

When the client starts, I render the view as so:

var view = new ServerListView({collection: Chatter.servers});
Chatter.Views.servers = view;
$('#channels > ul').html(view.render().el);

Works fine, events are called. Speaking of events those are:

 events: {
            "click .server": "server",
            "click .server ul li": "channel",
            "click .server .slider": "slide"
 },

The render method in question:

render: function(){
            var self = this;
            this.$el.html("");
            this.collection.each(function(server){
                self.$el.append(self.template(server.toJSON()));
                var header = self.$el.find('li.server[data-id="' + server.id + '"]')
                var connection = Chatter.Connections[server.id];
                if (connection) {
                    if (connection.channels.length > 0) {
                        connection.channels.each(function(channel) {
                            $(header).find("ul").append("<li data-channel-id=\"" + channel.id + "\">" + channel.get('name') + "</li>");
                        }, self);
                    }
                }

            }, self);
            this.delegateEvents();
            return self;
        },

Everytime this is called, it should re-render the view with all the Servers and Channels correctly. Everything renders correctly, but the events are not being called.

I re-render it the same way I render it:

$('#channels > ul').html(Chatter.Views.servers.render().el);

For whatever reason the above events are not being called when rendering it, any ideas?

Thanks

EDIT: I forgot to mention something:

If I re-render it with:

var view = Chatter.Views.servers;
$('#channels > ul').html(view.render().el);
view.delegateEvents();

Then it works just fine, which I know that would be okay, but I'm 99% sure I shouldn't have to do that, and I don't want to have to do that for every time that I re render the view.

Thanks again.

Jake
  • 407
  • 4
  • 13
  • Can you tell me why you do `html()` again with the `el` of that view? It has already been attached, there should be no need to reattach it this way. Note: the reason why the `delegateEvent()` within `render()` does not work is, because after rendering the view again, `html()` will do `empty()` (internally) which will do `cleanData()` (which removes event listeners) for the element and all its children. – try-catch-finally May 26 '15 at 07:42

1 Answers1

1

This stackoverflow question might help. Do you have an initialize function for the view? Maybe the initialize function could accept an argument (the jQuery object that specifies where the view should render into), so that it renders itself into the proper place on the page, then you can delegate the events within the initialize function if the events aren't delegated automatically.

In any case, I'd be intrigued to hear from others.

Community
  • 1
  • 1
turnloose
  • 101
  • 5
  • This is what I ended up doing. I passed a selector to the initialization of the view, and just set the HTML of the element in the render function, instead of after it was rendered. This worked, but I was really hoping to find a way around this, because I don't like binding the view classes to the DOM directly. Thank you though! – Jake May 26 '15 at 02:40