Backbone TypeError view is not a constructor

2019-08-29 01:45发布

I'm trying an example from 'Developing Backbone.js applications' book. I've reproduced part of the code below. When app.js is invoked, I get the following error in renderBook method of LibraryView (library.js).

TypeError: app.BookView is not a constructor

Can someone help me please?

// View for book (site/js/views/book.js)

var app = app || {};

app.BookView = Backbone.View.extend({
    tagName: 'div',
    className: 'bookContainer',
    template: _.template( $('#bookTemplate').html() ),

    render: function() {
        // tmpl is a function that takes a JSON object and returns html

        // this.el is what we defined in tagName. use $el to get access 
        // to jQuery html() function
        this.$el.html( this.template( this.model.toJSON() ));

        return this;
    }
});

//View for library (site/js/views/library.js )

var app = app || {};

app.LibraryView = Backbone.View.extend({
    el: '#books',

    initialize: function( initialBooks ) {
        this.collection = new app.Library( initialBooks );
        this.render();
    },

    // render library by rendering each book in its collection
    render: function() {
        this.collection.each(function( item ) {
            this.renderBook( item );
        }, this );
    },

    // render a book by creating a BookView and appending the
    // element it renders to the library's element
    renderBook: function( item ) {
        var bookView = new app.BookView({
            model: item
        });
        this.$el.append( bookView.render().el );
    }
});

// The main app (site/js/app.js)

var app = app || {};

$(function() {
    var books = [
        { title: 'JavaScript: The Good Parts', author: 'Douglas Crockford', 
          releaseDate: '2008', keywords: 'JavaScript Programming' },
        { title: 'The Little Book on CoffeeScript', author: 'Alex MacCaw', 
          releaseDate: '2012', keywords: 'CoffeeScript Programming' },
        { title: 'Scala for the Impatient', author: 'Cay S. Horstmann', 
          releaseDate: '2012', keywords: 'Scala Programming' },
        { title: 'American Psycho', author: 'Bret Easton Ellis', 
          releaseDate: '1991', keywords: 'Novel Splatter' },
        { title: 'Eloquent JavaScript', author: 'Marijn Haverbeke', 
          releaseDate: '2011', keywords: 'JavaScript Programming' }
    ];

    new app.LibraryView( books );
});

The html file includes all the JS in the following order:

<script src="js/lib/jquery.min.js"></script>
<script src="js/lib/underscore-min.js"></script>
<script src="js/lib/backbone-min.js"></script>
<script src="js/models/book.js"></script>
<script src="js/collections/library.js"></script>
<script src="js/views/book.js"></script>
<script src="js/views/library.js"></script>
<script src="js/app.js"></script>

Thanks.

1条回答
对你真心纯属浪费
2楼-- · 2019-08-29 02:00

Try wrapping your BookView & LibraryView declarations in onload $(function() {} blocks. Thats the only thing I can think of. Backbone.View.Extend is a function, and thus needs to be executed.

The way your currently doing it, you are setting app.BookView equal to the function Backbone.View.Extend, not the value returned by the function.

查看更多
登录 后发表回答