1

I'm trying to get my head around Backbone and it's concepts. I've made a simple app so that I can learn how to learn more about Backbone.Router and how to integrate Backbone with Require.js.

The app works great in Chrome, IE9 and Safari, however in the latest version of Firefox it throws a "TypeError: this.model is undefined" error after the click event is triggered and consumed. Thanks very much for any help!

I've attached a link to the entire app below for convenience.

https://dl.dropbox.com/u/19138757/Backbone_Example.zip

I'll comment on the method where the error is occuring:

document.js

    define([
        'jquery',
        'underscore',
        'backbone',
        'app'
    ], function ($, _, Backbone, app) {

        var DocumentListView = Backbone.View.extend({
            tagName: 'li',

            events: {
                'click': function () {
                    app.aggregator.trigger('document:selected', this.model);
                }
            },

            render: function () {
                this.$el.html(this.model.get('title'));
                return this;
            }
        });

        return DocumentListView;

    });

documents.js

    define([
        'jquery',
        'underscore',
        'backbone',
        'data/documents',
        'app',
        'text!templates/documents.html'
    ], function ($, _, Backbone, documents, app, documentTemplate) {

        app.aggregator.on('document:selected', function (document) {

            var urlPath = 'view/' + document.get('title');

            app.router.navigate(urlPath, { trigger: true });

        });

        DocumentView = Backbone.View.extend({
            el: $('#my-container'),

            template: _.template(documentTemplate),   

            events: {
                'click h1': 'sayHello'
            },

            // This is the method where the error is occuring. 
            // this.model is undefined...but ONLY in Firefox
            render: function () {
                this.$el.empty().append(this.template(this.model.toJSON()));
                return this;
            },

            sayHello: function () {
                this.input = this.$('.message');
                alert(this.input.val());
            }

        });

        return DocumentView;

    });

router.js

        define([
        'jquery',
        'underscore',
        'backbone',
        'data/documents',
        'views/contents',
        'views/document'

    ], function( $, _, Backbone, documents, ContentsView, DocumentView ){

        var DocumentRouter = Backbone.Router.extend({
            routes: {
                'contents': 'contents',
                'view/:title': 'viewDocument'
            },

            contents: function(){
                $('body').html(new ContentsView({collection: documents}).render().el);
            },

            viewDocument: function(title){

                //get a single document instance by title and then pass into DocumentView
                var selectedDocument = _(documents).find(function(document){
                    return document.get('title') === title;
                });

                $('body').empty().append(new DocumentView({model: selectedDocument}).render().el);
            }
        });

        return DocumentRouter;

    });
cpeele00
  • 883
  • 4
  • 14
  • 29

1 Answers1

2

Your problem is related to how different browsers handle spaces in the URL. Change your viewDocument function inside router.js to the following:

    viewDocument: function(title){
        // ADD THIS LINE
        title = decodeURIComponent(title);

        //get a single document instance by title and then pass into DocumentView
        var selectedDocument = _(documents).find(function(document){
            return document.get('title') === title;
        });

        $('body').empty().append(new DocumentView({model: selectedDocument}).render().el);
    }
Lukas
  • 9,765
  • 2
  • 37
  • 45