Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone Model array property change and change event listener not always firing [duplicate]

I found something strange in Backbone using change events. It's with an Model wich has an Array as property. And if I get the property push a new value inside and set it back to the model the change event is not fired...

Here's a fully documented example:

var TestModel = Backbone.Model.extend({
    defaults : {
        numbers : []
    },

    initialize : function() {
        this.on('change:numbers', this.changedEvent);
    },

    changedEvent : function() {
        console.log('model has changed');
    }
});

var oTestModel = new TestModel();
    oTestModel.set('numbers', [2, 3, 4]);    // change:numbers Event is fired

var aNumbers = oTestModel.get('numbers');
    aNumbers.push(5);

oTestModel.set('numbers', aNumbers);    // change:numbers event is NOT fired BUT WHY???

// oTestModel.set('numbers', [2, 3, 4]); 
// If this line is not commented out change:numbers event is also fired

console.log(oTestModel.toJSON());  // Dumps out [2,3,4,5] Respective [2,3,4] if line above is not commented out

Thx in advance.

like image 322
Bernhard Avatar asked Aug 08 '13 23:08

Bernhard


1 Answers

hesson is absolutely right about:

Arrays in JavaScript are treated as pointers, so mutating the array will not change the pointer, and no "change" event is fired.

However, as an alternate solution (if you are also using underscore.js) you can just do:

var aNumbers = _.clone(oTestModel.get('numbers'));
aNumbers.push(5);

oTestModel.set('numbers', aNumbers); //Will trigger the changed:numbers event

As seen in the answer to this similar problem: Backbone.js : change not firing on model.change()

This will duplicate the object instead of making it a reference, however nested objects or arrays will be only references.

like image 160
Sean Montana Avatar answered Sep 19 '22 08:09

Sean Montana