Search code examples
javascriptbackbone.jsrenderel

Backbone Body element View not Rendering


I'm having some issues with Backbone View rendering. Could anyone point at my mistake?

var BookView = Backbone.View.extend({
    template: _.template('<strong><%= title %></strong> - <%= author %>'),
    tagName: 'div',
    className: 'cover',
    id: '',
    initialize: function() {
        console.log('View initialized');
        this.render();
    },
    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

var instance = new Book({
    title: 'Thinking, Fast and Slow',
    author: 'Daniel Kahneman',
    issued: '2011'
});
console.log(instance.get('title') + ' by ' + instance.get('author') + ' added to catalogue');

var something = new BookView({model: instance, el: $('body')});
something.render();

The thing is that I'm reading documentation as well as Backbone Fundamentals book and not getting why after el: $('body') View is not appended to body tag.

At the same time $('body').append(something.el); from console works perfectly, but doesn't make me feel that I understand framework concept.


Solution

  • To extend briefly on what @TJ has mentioned, it's worthwhile noting that there is difference between el and $el.

    $el is a cached jQuery (or Zepto) reference to the view's element: (Since v0.9.0)

    A cached jQuery object for the view's element. A handy reference instead of re-wrapping the DOM element all the time.

    this.el can be resolved from a DOM selector string or an Element:

    this.el can be resolved from a DOM selector string or an Element; otherwise it will be created from the view's tagName, className, id and attributes properties. If none are set, this.el is an empty div


    To get you current code working, all you need to do is remove the tagName, id and className properties:

    var BookView = Backbone.View.extend({
        template: _.template('<strong><%= title %></strong> - <%= author %>'),
        initialize: function() {
            this.render();
        },
        render: function() {
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        }
    });
    

    Since you are calling render() from initialize, you don't need to call it again after it has been initialized:

    var something = new BookView({model: instance, el: $('body')});
    


    Here is a Fiddle with your working code