Question

I'm using Backbone.js 1.1.2 with jQuery 1.11.

I think I'm missing something very simple.

I've set up a model: Contact and a collection: ContactList.

I have success rendering ContactView views with models obtained from ContactList.fetch()

But when I try to bind a change event in the view initializer:

this.model.on('change', this.render, this);

... I get:

backbone Uncaught TypeError: Object #<Object> has no method 'on'

So I go back to the documentation and read that .on() is part of Backbone.Events, and somehow I need to extend my model to use this (and why is this not part of the out-of-the-box functionality for models??)

I've tried declaring

_.extend(this, Backbone.Events); 

... inside of the initialize function for ContactView before declaring the binding, but no dice.

What do I need to do to get the Backbone.Events functionality working??

update: all relevant code (sans template)

var Contact = Backbone.Model.extend({
    defaults: {
        FirstName: '',
        ...[etc]
    },
    initialize: function() {
    }
});

var ContactList = Backbone.Collection.extend({
    model: Contact,
    url: '/api/Contacts/getall'
});

var ContactView = Backbone.View.extend({        
    initialize: function() {
        this.render();
        this.model.on('change', this.render, this);
    },
    render: function () {
        var template = _.template($('#contact_template').html(), this.model);
        this.$el.html(template);
    }
});

var contactList = new ContactList();

contactList.fetch({
    success: function (collection, response, options) {
        contactList.models.forEach(function (m) {
            var $el = $('<li />')
                .addClass('adminItem clearfix')
                .appendTo($('#contactList'));
            new ContactView({ el: $el, model: m.attributes });
        });
    }        
});
Was it helpful?

Solution

This line is the source of trouble

new ContactView({ el: $el, model: m.attributes });

m.attributes is a plain js object. You want to pass along the actual model object:

new ContactView({ el: $el, model: m});

And because the collection has underscore methods mixed in you should be able to simplify it a bit to this:

    contactList.each(function (m) {
        var $el = $('<li />')
            .addClass('adminItem clearfix')
            .appendTo($('#contactList'));
        new ContactView({ el: $el, model: m});
    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top