streetlight
streetlight

Reputation: 5968

Changing nested attribute with model.set in Backbone

I'm trying to do what I hope is a simple thing -- doing a model.set only on a sub attribute of the object.

Right now, I have a model that looks like this:

{
            "attr1" : true,
            "attr2" : this.model.get("username"),
            "attr3" : $('#tenant_select').val(),
            "attr_array": [
                {
                    "id": "sub_1",
                    "state": "active"
                },
                {
                    "id": "sub_22",
                    "state": "not_active"
                }
            ]
        }

I want to be able to grab reach into myMode.attr_array.state and change the value. However, using .set I've only been able to change attributes on the first level, i.e. attr_array.

Is there an way to do this using model.set?

Upvotes: 3

Views: 5603

Answers (1)

Loamhoof
Loamhoof

Reputation: 8293

You can do it (I'm wondering why you didn't manage to do it). But you have to be careful:

var array = this.get('attr_array');
array[1].state = 'active';
this.set('attr_array', array);

What's the problem here? Your model holds a reference of the object. Therefore the last line is useless, it won't change anything at all. It's simply equivalent to:

this.get('attr_array')[1].state = 'active';

And you lose any internal stuff Backbone does when you use set.
So what to do? Clone your object:

var array = _.clone(this.get('attr_array'));
array[1].state = 'active';
this.set('attr_array', array); // will trigger 'change' and 'change:attr_array' events

Upvotes: 18

Related Questions