8

This is my app.js file. I need to access the router's navigate method from within the navigateToLogin method of the LandingView class. But since the appRouter is defined after the view it can't recognize the router from within the view. So I need to find a way to globally access the router from any class or method. How can I get around this problem?

var LandingView = Backbone.View.extend({
    tagName: 'div', 
    id: 'landing',
    className: 'landingpad',
    events: {
        'click button#login': 'navigateToLogin',
    },
    render: function (){

        (this.$el).append("<button class='button' id='login'>Login</button><br/><br/><br/>");
        (this.$el).append("<button class='button' id='new'>New User?</button>");

        console.log(this.el);
        return this;
    },
    navigateToLogin: function(e){
        app.navigate("/login", true);
        return false; 
    },
});

var appRouter = Backbone.Router.extend({

initialize: function(){
    $('#content').html(new LandingView().render().el);
}
});

    app = new appRouter();
jaykumarark
  • 2,359
  • 6
  • 35
  • 53

2 Answers2

20

If you dig into Backbone's code a little, you'll notice that the router's implementation of navigate in turn calls Backbone.history.navigate:

// Simple proxy to `Backbone.history` to save a fragment into the history.
navigate: function(fragment, options) {
  Backbone.history.navigate(fragment, options);
}

So instead of explicitly mucking up the global scope, use Backbone.history.navigate:

var LandingView = Backbone.View.extend({
    ...
    navigateToLogin: function(e){
        Backbone.history.navigate("/login", true);
        return false; 
    },
});
Lukas
  • 9,765
  • 2
  • 37
  • 45
  • I solved the navigation problem. I omitted the slashes in the navigate function and it worked :) But thanks for the info. Its interesting to learn that there is always more than one way to solve a problem :) – jaykumarark Dec 20 '12 at 06:21
7

If you need appRouter to be accessible globally, you have to attach it to some global object. In web browsers this is the window object.

window.app = new appRouter();

And access it via window:

window.app.navigate(...);

Using globals can lead to code that's difficult to maintain. If your app is not of trivial size, consider using some decoupling mechanism, such as the mediator pattern.

jevakallio
  • 35,324
  • 3
  • 105
  • 112
  • Well I'm making a small app which is quite manageable and purely for educational purposes. It worked. Thanks :) – jaykumarark Dec 19 '12 at 13:30
  • ` routes:{ "" : "init" "/login": "loadLogin", },` My router doesn't seem to trigger the loadLogin function of my router. Is there anything wrong with the above statement? – jaykumarark Dec 19 '12 at 13:33
  • @jaykumarark not sure, try defining the route without the leading forward slash. – jevakallio Dec 19 '12 at 13:38
  • Anyways thanks for the help. I think there is probably some syntax error. I ll look into it :) – jaykumarark Dec 19 '12 at 13:41