kramer65
kramer65

Reputation: 53873

How to only update a Backbone view if the collection changed on the server?

I've got a page for which I poll for notifications. If there are any notifications I populate a Backbone.js view with the notifications. I currently poll for notifications every 2 seconds and simply repopulate the view every two seconds.

function updateNotificationView(ticketId) {
    var ticketNotificationCollection = new TicketNotificationCollection([], {id: ticketId});
    $.when(ticketNotificationCollection.fetch()).done(function() {
        var notificationView = new NotificationsView({collection: ticketNotificationCollection});
        $('#ticket-notifications-area').html(notificationView.render().el);
    });
}
window.notificationsIntervalId = setInterval(function() {updateNotificationView(ticketId);}, 2000);

I now want to only populate the view if the Backbone fetched collection has changed, but I have no idea how I could do that?

Could anybody give me a tip on how I could only populate the view on collection change? All tips are welcome!

[EDIT] I now changed the function to this:

function updateNotificationView(ticketId) {
    var ticketNotificationCollection = new TicketNotificationCollection([], {id: ticketId});
    var notificationsView = new NotificationsView();
    notificationsView.listenTo(ticketNotificationCollection, 'change', notificationsView.render);
    notificationsView.listenTo(ticketNotificationCollection, 'add', notificationsView.render);
    ticketNotificationCollection.fetch();
}

and I changed the NotificationsView to this:

var NotificationsView = Backbone.View.extend({
    addNotificationView: function(notification) {
        var singleNotificationView = new SingleNotificationView({model: notification});
        this.$el.append(singleNotificationView.render().el);
    },
    render: function() {
        console.log('ITS BEING CALLED!!');
        this.collection.each(this.addNotificationView, this);
        $('#ticket-notifications-area').html(this);
    }
});

I now get the "ITS BEING CALLED!!" in the console every two seconds, but also an error: "Uncaught TypeError: Cannot read property 'each' of undefined.". I get why this error occurs; its because the collection is never actually inserted into the view. I don't get however, how I can solve this.. Any more tips?

Upvotes: 0

Views: 364

Answers (1)

jsist
jsist

Reputation: 5253

I am assuming that you are getting models in the collection in response to your request as JSON.

Method 1:

You can simply set the collection to the JSON. and bind the collection to change event. In case of any change in the collection, callback function will be triggered. In the callback function you can render your view.

Note: change event on collection will be triggered only if there is any change in the models it contain.

e.g.

someCollection.on('change', function(){
    someView.render()
  });

Method 2:

You can use Backbone's listenTo method, to render the view on change of collection.

someView.listenTo(someCollection, 'change', someView.render);

Hope it helps...

Upvotes: 3

Related Questions