Search code examples
javascriptbackbone.js

Correct way to trigger backbone model change event


I am trying to create simple Backbone example but i don't understand what is the problem with my code. Why is there 2 testAttr attributes(on directly on object and one in attributes object) and why isn't change event triggering on any of the changes? Also i don't understand what is the correct way to set attributes on model?

Heres my code:

<div id="note"></div>
<script>
var NoteModel = Backbone.Model.extend({
    defaults: function() {
        return {
            testAttr: "Default testAttr"
        }
    }
});

var NoteView = Backbone.View.extend({
    initialize : function() {
        this.listenTo(this.model, "change", this.changed());
    },
    el: "#note",
    changed: function () {
        debugger;
        console.log("change triggered");
        this.render();
    },
    render : function() {
        this.$el.html("<h1>" + this.model.get("testAttr") + "</h1>");
        return this;
    }
});

var note = new NoteModel();

var noteView = new NoteView({model: note});
noteView.render();

note.set("testAttr", "blah1");
note.testAttr = "blah2";
</script>

Solution

  • Change this line:

    this.listenTo(this.model, "change", this.changed());
    

    to this:

    this.listenTo(this.model, "change", this.changed);
    

    For the second part of your question, using .set() goes through a set of dirty-checking to see if you changed, deleted or didn't change anything, then triggers the appropriate event. It isn't setting the object.property value, it's setting the object.attributes.property value (tracked by backbone.js). If you directly change the object property, there's nothing to initiate that event for you.

    ...unless of course you use the AMAZING AND TALENTED Object.observe()!!!1! - ITS ALIVE (in Chrome >36)