How to access router globally in backbone js?
Asked Answered
E

2

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();
Eubanks answered 19/12, 2012 at 13:4 Comment(1)
Lukas's answer should be the accepted answer to this question.Gargoyle
O
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; 
    },
});
Outport answered 19/12, 2012 at 18:43 Comment(1)
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 :)Eubanks
M
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.

Middaugh answered 19/12, 2012 at 13:21 Comment(4)
Well I'm making a small app which is quite manageable and purely for educational purposes. It worked. Thanks :)Eubanks
` 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?Eubanks
@Eubanks not sure, try defining the route without the leading forward slash.Middaugh
Anyways thanks for the help. I think there is probably some syntax error. I ll look into it :)Eubanks

© 2022 - 2024 — McMap. All rights reserved.