11

I bind on the change event of my backbone models like this.

this.model.on( "change", this.render, this );

Sometimes I want to fetch the latest version of the model and forcibly render the view. So I do this

this.model.fetch();

Unfortunately model.fetch() only fires the change event if the new data is different from what was previously stored in the model.

How can I always trigger a this.render callback when fetch completes, whether it triggers a change event or not?

Thanks (in advance) for your help

user1031947
  • 6,294
  • 16
  • 55
  • 88

4 Answers4

13

You can use the $.ajax success callback, but you can also just listen for the Backbone sync and error events on the model. sync fires after a successful call to the server, error fires after a failed call to the server.

this.model.on('sync', this.render, this);
this.model.on('error', this.handleError, this);
Ben
  • 10,056
  • 5
  • 41
  • 42
1

The fetch method can optionally accept has success and error callbacks; the simplest solution is to put you view's render in the success callback. You could also probably use the returned jqXHR promise, but if there's ever a case where the AJAX would be successful (per jQuery) but model initialization fails, that usage could be problematic.

JayC
  • 7,053
  • 2
  • 25
  • 41
1

I don't know what is your code structure, however if your are fetching your model inside your view, you can use something like this

var that = this;
this.model.fetch().done(function () {
    that.render();
});

else, if your are fetching your model outside your view, you can pass your promise to your view and make something similar

var promise = model.fetch();
// other code here
var view = new View({
    model: model,
    promise: promise
});

and inside your view, for example in initialize

View = Backbone.View.extend({
    initialize: function(){
        this.options.promise.done(function () {
            // your code here
        });
    }
});
Hayk Aghabekyan
  • 1,087
  • 10
  • 19
1

How about this solution:

// emit fetch:error, fetch:success, fetch:complete, and fetch:start events
fetch: function(options) {
  var _this = this;

  options = options || {};

  var error = options.error;
  var success = options.success;
  var complete = options.complete;

  options.error = function(xhr, textStatus, errorThrown) {
    _this.trigger('fetch:error');
    if (error) error(xhr, textStatus, errorThrown);
  };

  options.success = function(resp) {
    _this.trigger('fetch:success');
    if (success) success.call(options.context, resp);
  };

  options.complete = function() {
    _this.trigger('fetch:complete');
    if (complete) complete();
  };

  _this.trigger('fetch:start');

  return Backbone.Model.prototype.fetch.call(this, options);
}

Link to gist https://gist.github.com/fedyk/23761ce1236c5673fb84