2

Basically I want this set up:

var Game = Backbone.Model.extend({
    defaults: {
    },
    autoSync: true
});

var Games = Backbone.Firebase.Collection.extend({
    url: 'https://<myapp>.firebaseio.com/games',
    autoSync: false,
    model: Game
});

Each Game should be auto-synced with server data but I do not not want to listen to the entire child_* Firebase family of events. The goal is to update individual item view instead of repainting the whole list.

Kind regards to folks out there and happy coding ;)

David East
  • 31,526
  • 6
  • 67
  • 82
Khanh Hua
  • 1,086
  • 1
  • 14
  • 22

1 Answers1

2

You can update individual items by using an Backbone.Firebase.Collection with autoSync enabled. To do re-render individual items you need to listen to when the items fire the change event. This concept is shown in the BackboneFire Quickstart in the Firebase docs.

A quick note however, you cannot mix a Backbone.Firebase.Model with a Backbone.Firebase.Collection.

Todo Model & Collection

In the below sample, notice how a regular Backbone.Model is being used in the Backbone.Firebase.Collection. The collection by default has autoSync enabled.

// A simple todo model
var Todo = Backbone.Model.extend({
  defaults: { title: "New Todo" }
});

// Create a Firebase collection and set the 'firebase' property
// to the URL of your Firebase
var TodoCollection = Backbone.Firebase.Collection.extend({
  model: Todo,
  url: "https://<your-firebase>.firebaseio.com"
});

Todo View

The below sample is a view for an individual todo item. Inside of the initialize function the listenTo method is used to listen to a model's change event. The change event will be fired each time the model is updated either remotely or locally (which persists changes remotely).

// A view for an individual todo item
var TodoView = Backbone.View.extend({
  tagName:  "li",
  template: _.template("<%= title %>"),
  initialize: function() {
    // whenever the model changes trigger a re-render of the single view
    this.listenTo(this.model, "change", this.render);
  },
  render: function() {
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  },
});

Render List

With the TodoView set up the list can easily be rendered as well. In the initialize function of the AppView below, we listen to the collection which will be a TodoCollection. Whenever an item is added to the collection the addOne function is executed. The addOne function simply appends a new TodoView to the page.

// The view for the entire application
var AppView = Backbone.View.extend({
  el: $('#todoapp'),
  initialize: function() {
    this.list = this.$("#todo-list"); // the list to append to

    // by listening to when the collection changes we
    // can add new items in realtime
    this.listenTo(this.collection, 'add', this.addOne);
  },
  addOne: function(todo) {
    var view = new TodoView({model: todo});
    this.list.append(view.render().el);
  }
});
David East
  • 31,526
  • 6
  • 67
  • 82
  • Thanks David. I set it up wrong at first. My solution is slightly different. First I listen once to the `sync` event, then iterate thru the collection, render the items. For each of the item view I listen to the `change` event as you mentioned. To handle the add and remove I use separate two handlers on the list view and item view, respectively. So basically the keys are a combination of `sync` once on collection -> `change`, `remove` on each item and `add` on the collection. Any suggestions? – Khanh Hua Dec 18 '14 at 23:42