1

I'd appreciate any insight into whether this is a "correct" way of doing things and also what's causing the error I'm seeing.

I have added backbone to my base meteor install meteor add backbone

Then I set up a router.js file as follows (just showing 2 pages as example);

var Router = Backbone.Router.extend({
  routes: {
    "":                 "index", 
    "help":             "help",  
    ... 
  },

  index: function() {
    Session.set('currentPage', 'homePage');
  },

  login: function() {
    Session.set('currentPage', 'loginPage');
  },

  ... 

Then for the pages I have html files with templates looking something like this...

<template name="homepage">
    {{#if route}}
    You're at the Home Page!
    {{/if}}
</template>

Then for the main page I have an html file that contains the following;

<body> 
...
    {{> homepage}}
    {{> loginpage}} 
    {{> helppage}}
...
</body>

This works for all of the pages except the one designated 'homepage', this template is always rendered regardless of where I am on the site. e.g. myapp/ as the root page just displays the homepage template, but myapp/loginpage displays the loginpage template and the homepage template. So every single page displays the contest of the homepage template.

Any insight? (or better ways to structure).

Thank you

Kate Price
  • 25
  • 4
  • After typing all that out and thinking about it I'm imagining it's because the "" matches the root url of my site, and so that it returns you're on the "index" page no matter where you are on the site. If that is the case, is there a way around that? I would have imagined having the session variable set not to 'homePage' should fix that. – Kate Price Apr 30 '13 at 21:05
  • You may have to define your initial/base url in the backbone history start. Look at the answer to this question http://stackoverflow.com/questions/9368151/define-a-base-url-in-backbone-js-router – Warz May 01 '13 at 15:53

1 Answers1

3

Finally a question that I can answer because it's what I've been doing 60 hours a week at work for the last few months :-P

You're doing a few things wrong here, and they're extremely simple fixes that will get you fired up in no time.

First thing

You need to instantiate all of your routers and then initialize Backbone.pushState().

// This is just how I have been doing it, there are many correct ways.
var LoadedRouters = {
    Module1 : new Module1Router(),
    Module2 : new Module2Router(),
    ...
};
// After all routes instantiated, we tell Backbone to start listening.
Backbone.history.start({ pushState : true, root : "/" });

It's very important that you set the root property correctly, or else weird things start happening.

Second thing

You HAVE TO list your routers from the most-specific to the least-specific, top-down. The URL structure you outlined above will ALWAYS match the first route and trigger it.

routes : {
    "help/phones/newservice" : HandleNewServiceHelp(),
    "help/phones/oldservice" : HandleOldServiceHelp(),
    "help/phones(/:any)" : HandleAllPhoneHelp(),
    "help(/:any)" : HandleAllHelp(),
    "" : HandleAllUnmatchedRoutes()
};

Backbone.router can be a tricky thing to learn.

Community
  • 1
  • 1
Pierce
  • 325
  • 4
  • 10
  • So, first and second thing, then what Kate did? – Prashant Aug 20 '13 at 05:55
  • For the most part, yes. The code snippet in `Second Thing` is merely a map of the routes that the router matches, and represents the `Router.routes` property of whatever Router it lives inside. Also contained within that router are functions `HandleNewServiceHelp`, `HandleOldServiceHelp`, `HandleAllPhoneHelp`, `HandleAllHelp`, and `HandleAllUnmatchedRoutes`. All methods supplied as the route action inside the `routes` mapping need to have an identically-named function inside the same router. **The functions DO NOT map to functions outside the router.** (I think.) – Pierce Aug 25 '13 at 10:45