Levi Hackwith
Levi Hackwith

Reputation: 9332

HasChanged Not Working in Backbone 1.1.2

CodePen: http://codepen.io/opnsrce/pen/hclaH

Expected behavior: You should only be able to highlight one item at a time.

Current Behavior: You can highlight multiple items

Cause: HasChanged returns true when checked by the controller during the change event.

When I run this code with Backbone 0.9.2 it works. When I use 1.1.2 it doesn't.

Did something fundamentally change in the way hasChanged works between those two versions?

Upvotes: 0

Views: 100

Answers (1)

glortho
glortho

Reputation: 13198

I believe this is the desired functionality. A model's changed attributes change each time the model itself is set. So until you set a model multiple times it will hold onto its changes. The code you've set up here would work if that hash of changes cleared out when a different model was selected. What is actually happening is that as soon as you set a model to isSelected it will always have isSelected == true and hasChanged('isSelected'), so it will never pass the condition to set isSelected to false.

One way to accomplish what you're looking for is to change your collection method to this:

onSelectedChanged: function(modelActive) {
  if(modelActive.get('isSelected') === true){
    this.each(function(model) {
      if (model != modelActive) {
        model.set({isSelected: false});
      }
    });
  }
}

Note that I took out hasChanged since that was simply confirming that a model had changed at some previous point. Instead I compare the actively selected model with the ones being iterated. We don't want to touch the active one. I also check to see if this method was triggered via the setting of isSelected to true because if we don't do that, every setting of the iterated models to false will trigger this method and cause problems.

The only limitation of this is that you can't select the same item to toggle it off.

Upvotes: 1

Related Questions