1

Here's the scenario - a page renders a collection of widgets that display some aggregated data to the user. This data is retrieved from an API, and is regularly re-calculated. Displaying these are fine (thanks to the fine folks at stackoverflow), but I'm just having trouble re-rendering the views when data is changed on the server.

Notably, I would prefer the more efficient approach of not re-rendering all the pages' widgets (could be 10+) if only one has updated data. Fetching a collection at an interval is easy enough, but what are the best practices regarding rendering a chaned model? I've seen various posts about overwriting the sync function, but not really sure where to go.

Is there any way we can re-render the view(s) in-place (rather than re-appending to the page).

Thanks so much

crawf
  • 9,448
  • 10
  • 33
  • 43

2 Answers2

2

I think what you need is update the existing Models into the Collection without refresh the whole Collection. Check my answer here.

Community
  • 1
  • 1
fguillen
  • 36,125
  • 23
  • 149
  • 210
  • that seems like a nice utility function, but how should it be called? Once fetch() is called, it will overwrite the collection before I can call this function to update (instead of reset). – crawf Apr 15 '12 at 00:44
  • 1
    You have to use an extra _temporal_ `Model` to fetch the raw JSON data and from here use the `App.Utils.refreshCollection()` method to _refresh_ the real `Collections` without calling `fetch()` on them. – fguillen Apr 15 '12 at 10:29
  • Aha, I see what you mean now! Thanks for the tip - I'm actually using breischl's answer from the above link, but i'd prefer to not be changing the source. I'll give your solution a go, and see how it goes. Thanks! – crawf Apr 15 '12 at 11:03
  • yes, breischl's answer and mine both follow the same concept. Just beware breischl's answer code has not support `remove` elements from the _refreshed_ `Collection`. Not difficult to add it either. – fguillen Apr 15 '12 at 14:26
1

You can bind to specific changes on the model/collection to trigger the render methods of the widgets. For example, on a model:

var Widget1=Backbone.View.extend({
    initialize: function() {
        // all changes on the model will render the widget
        this.model.on("change", this.render, this); 
    },

    render: function() {
        console.log("Render W1");
        this.$el.html("W1 :"+this.model.get("name")+" "+this.model.get("detail"));
        return this;
    }
});
var Widget2=Backbone.View.extend({
    initialize: function() {
        // only a change on `detail` will render the widget
        this.model.on("change:detail", this.render, this);  
    },

    render: function() {
        console.log("Render W2");
        this.$el.html("W2 :"+this.model.get("detail"));
        return this;       
    }
});

A more complete Fiddle to play with http://jsfiddle.net/GqnKC/

nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • yup, I was playing around with that before, but the 'change' event doesn't fire, because the fetch() will completely replace the collection (as such, the collection hasn't changed). – crawf Apr 15 '12 at 00:48