17

It's a known feature of backbone.js that when you set data that hasn't changed it won't fire the change event, nor will it go through validations. I however need the change event to fire as I'm storing a JSON response from an AJAX call which stores results of backend validation. If the user keeps submitting the form while leaving the same field empty, the backend validation will return the same JSON result and when I save it to the model it won't trigger the change event.

A few things I've tried within the AJAX success callback where I set the data into the model:

Attempted Solution #1

t.model.unset('fieldErrors',{silent: true});
t.model.set({fieldErrors: JSONResponse});

Attempted Solution #2

t.model.set({fieldErrors: null},{silent: true});
t.model.set({fieldErrors: JSONResponse});

Neither of these results in the change event firing a second time when the call is made and the user has the same JSONResponse.

  • If you're not afraid of boilerplate, see ScottPuleo's answer. Otherwise, you can override the `Model#set` method to always fire a custom event (I'll post an answer on how if you're interested). – Loamhoof Apr 11 '13 at 22:29

2 Answers2

26

Manually trigger the change event:

t.model.trigger('change', t.model);

or

t.model.trigger('change:fieldErrors', t.model, newFieldErrorsValue);
Chris
  • 5,876
  • 3
  • 43
  • 69
Scott Puleo
  • 3,684
  • 24
  • 23
  • 5
    That second case (of a random option) should probably never be used. The `trigger` method is all that's needed here. Remember to pass along the parameters necessary as backbone won't do it for you when you manually trigger. – Adam Terlson Sep 02 '14 at 22:31
  • 2
    Note: "That second case" refers to an old case which since has been removed. – Chris May 06 '15 at 22:42
  • @Scott Puleo This is an old question but I was wondering if you could explain why we need to pass the model itself as a second argument to `trigger`? When I don't, `Collection._onModelEvent` - which is called later - doesn't receive the model. It seems to me that `model.trigger('change')` should be enough to forward the model to that later event. Do you know why it is not? (sorry if my question is not clear...) – Arnaud Aug 17 '15 at 23:16
  • Oh well, should have searched a bit more before asking. Looks like a bug: https://github.com/jashkenas/backbone/issues/3717 – Arnaud Aug 17 '15 at 23:23
0
this.model.set({fieldErrors: JSONResponse}, {silent:true});
this.model.trigger('change:fieldErrors');

see this conversation:

Can I force an update to a model's attribute to register as a change even if it isn't?

Noam Rones
  • 13
  • 2