Reputation: 9859
My goal is to switch from one page to another. While I know how to do this with Iron-Router I want to program it myself since I am teaching Meteor to people who have windows, and therefore no Iron-Router.
Edit: SUB-QUESTION:Which 3 methods proposed here is more efficient?
My first approach:
//HTML
<body>
{{>mainTemplate}}
</body>
//Cliente JS Initially
Session.set('current', 'initialTemplate')
Template.mainTemplate = function()
{
return Template[Session.get('current')];
};
//Later
Session.set('current', 'someOtherTemplate')
This works in a very Meteoric way BUT it requires a lot of manual strings that are not checked by the IDE and could induce errors. So my second approach is to solve this is:
//HTML
<body>
</body>
//JS Client Initially
UI.materialize( Template.initialTemplate, document.body );
//Later
$("body").html("");
UI.materialize( Template.someOtherTemplate, document.body );
This second approach uses variables and not strings, it's very readable, shorter, simpler and it works BUT I am a little skeptic about jQuery, I first used it today. Also, I don't know if its really convenient for Meteor's internals to just have chunks of HTML deleted. I Would prefer a pure Meteoric approach if possible.
Thanks in advance.
Edit This this pattern currently works like a charm! Can somebody find even a simpler one?
//HTML
<body>
{{>mainTemplate}}
</body>
//JS Client Initially
var current = Template.initialTemplate;
var currentDep = new Deps.Dependency;
Template.mainTemplate = function()
{
currentDep.depend();
return current;
};
function setTemplate( newTemplate )
{
current = newTemplate;
currentDep.changed();
};
//Later
setTemplate( Template.someOtherTemplate );
This pattern taken from this answer and this seccion in the Meteor docs.
Upvotes: 1
Views: 207
Reputation: 4138
I have not tried it but based on your code above I think this would work:
//HTML
<body>
{{>mainTemplate}}
</body>
//Cliente JS Initially
var current = Template.initialTemplate;
var currentDep = new Deps.Dependency;
Template.mainTemplate = function()
{
currentDep.depend();
return current;
};
//Later
current = Template.someOtherTemplate;
currentDep.changed();
This is just based off your 'ideal' solution but hopefully gets around the Session variable restriction to EJSON-able values.
Upvotes: 1
Reputation: 7356
I tackled this problem for an app I was building that had only six pages, where adding Iron Router felt like overkill. I built it like this:
<body>
{{> root}}
</body>
<template name="root">
{{#if currentPageIs "home"}}
{{> home}}
{{/if}}
{{#if currentPageIs "about"}}
{{> about}}
{{/if}}
{{! etc. }}
</template>
And then you define a Session variable currentPage
, which in my case could be home
or about
or the other four page names; and clicking on links or buttons to change pages really only updated the Session variable. Then the helper for this "poor man's router" looks like this:
Template.root.currentPageIs = function (page) {
return Session.equals("currentPage", page);
};
And that's it. No jQuery, no working with templates as strings (which should break under Meteor 0.8 with its new templating engine, I would think). It's fully Meteoric. Obviously with more than a handful of pages/routes, this approach gets quite tedious; but it requires no packages and it's very clear to understand for a Meteor novice.
For completeness, here's an example page and the helper to change pages:
<template name="home">
<p>Welcome to our website! You can learn more
<a href="#" id="goToAbout">about us</a>.</p>
</template>
and
Template.home.events({
"click #goToAbout": function (event, template) {
event.preventDefault();
Session.set("currentPage", "about");
}
});
Upvotes: 1