Search code examples
backbone.jsrequirejsamd

Require.js module not seeing Backbone Router.js


In this simple Require/Backbone app

https://github.com/thisishardcoded/require-prob

Why does app.js see Router but TestView.js not?

Here is the first line of app.js

define(['router'],function (Router) {

and here is the first line of TestView.js

define(['backbone','router'],function(Backbone,Router){

Check out the repo for full details, download, run and check console log if you feel so inclined

Thanks! Jim

More: Ok, the answer is - because of the order in which it is loaded and even if that were altered I have a circular dependency don't I? TestView needs Router, Router needs TestView.

In which case the solution might be

var r=require('router);
r.navigate or whatever

but, that seems like a shame that Router is not directly accessible everywhere and, is the above method good practice anyway?


Solution

  • Surely it happens because of circular dependency. To resolve it, you either pass router to view's constructor and remove router dependency from view's module, or use require('router') in your view.

    1st option, router.js:

    app_router.on('route:test', function () {
        var testView = new TestView({router: app_router});
        testView.render();
    })
    

    1st option, view.js:

    define(['backbone'], function(Backbone){
    
        var TestView=Backbone.View.extend({
            el: '#test',
            initialize: function() {
                // get router from constructior options
                this.router = this.options.router
            },
            render: function(){
                this.$el.html('<p>Foo!</p>');
                console.log("TestView.js does not find 'Router',", this.router);
            }
        });
    
        return TestView;
    
    });
    

    2nd option, view.js:

    define(['backbone','router'], function(Backbone, router){
    
        // at this point router module is not loaded yet so router is undefined
    
        var TestView=Backbone.View.extend({
            el: '#test',
            initialize: function() {
                // at this point router module is loaded and you may access it with require call
                this.router = require('router');
            },
            render: function(){
                this.$el.html('<p>Foo!</p>');
                console.log("TestView.js does not find 'Router',", this.router);
            }
        });
    
        return TestView;
    
    });
    

    2nd option is also described here: http://requirejs.org/docs/api.html#circular