Gabriel Cebrian
Gabriel Cebrian

Reputation: 395

Reset hasChanged() and changedattributes() on Backbone model

I am trying to reset the values on the changedAttributes() for a model. Here is my specific case:

I fetch a Quiz model from the server which downloads a Quiz, its Questions and the questions Answers. When the quiz is fetched, I parse the attributes for the quiz and generate Questions if they are present on the JSON that gets returned from the server. To parse such questions I create a Question model and then call an instance method called fromJSON passing the object that contains the question attributes. This method calls @parse and then @set on the model passing the object that was received from the server. You could think of the fromJSON method as populating the object's properties.

The issue I am having is that now I want to use the hasChanged() method on the Question models but this always return true since the fromJSON method uses @set(). I need a way to either "reset" the attributes that have been change so once I am done with the fromJSON method I can tell the model, 'hey, this is the latest model state from the server' so start tracking any change from now on and discard any changes from the past. Another way would be to be able to set the properties on the model without changing the changed internal value (used when calling changedAttributes() and hasChanged() ).

Code:

# Quiz model
class Quiz extends Backbone.Model
    parse: (response, options) ->
        attributes = response

        if attributes.questions
            attributes.questions = @createQuestions( response.questions )

        return attributes

    createQuestions: ( questions_json ) =>
        questions = new QuestionsCollection()

        # Parse every question
        for question_json in questions_json
            question = new Question()

            if question_json
                question.fromJSON( question_json )

        return questions

# Question model
class Question extends Backbone.Model

    # Get the model json and parse it and set its attributes
    fromJSON: (json , options ) =>
        return @set( @parse( json , options ) , { silent : true } )

Upvotes: 1

Views: 1250

Answers (1)

Feugy
Feugy

Reputation: 1918

If you are really sure of what you're doing, you can modify the Model inner values. Use the attributes hash. For example:

# Get the model json and parse it and set its attributes
fromJSON: (json , options ) =>
    values=  @parse json, options
    for attr, val of @parse json, options
      @validate
      @attributes[attr] = value

It's barely what set is doing, without comparing with the old values, triggering a change event, and storing the old values in previousAttributes.

But remember: you're bound to Backbone internal, which may change in future versions.

Upvotes: 1

Related Questions