I have one master layout that i have been using for my app.I have a generated my app using iron-cli package and my master layout is called master_layout.html
t i now have a problem. All my app menus are all in he master layout and i need to create a login page that will not require the menus. This can be solved,if i had a second master layout whereby i can strip the menus off my original master layout and use the layout for my login page.
My route looks like this
Router.route('/Limit/ay', {
name: 'ay',
controller: 'LimitController',
action: 'ay',
where: 'client'
});
and my controller code looks like this
ay: function() {
this.render('Ay');
//this.render('Added', {});
}
Is there a way i can register a second master layout and use it for my login page?.
If i register another layout
Router.configure({
layoutTemplate: 'MasterLayout',
loadingTemplate: 'Loading',
notFoundTemplate: 'NotFound'
});
Router.configure({
layoutTemplate: 'GoodLayout'
})
One layout is being used and the other is ignored,so i can only use one main layout at a time.
How can i solve this?.
Just override the layout in your new route:
Router.route('/Limit/ay', {
name: 'ay',
layoutTemplate: 'GoodLayout',
controller: 'LimitController',
action: 'ay',
where: 'client'
});
The route's version will take precedence over the global layout setting.
Related
I have the following routs
/product/123
/product/456
the template renders the product data and allows the user to drag things around
when I make a redirect to another product like that
Router.go("product",{_id:"456"});
the template updates the data but does not re-render the html. that means that what the user dragged stays in place. this is good for some cases but not for mine
the only solution that worked for me was to redirect to another page that sets clear template and it redirects to the product page
my router function:
Router.route('product/:_id/', {
name:"product",
data:function(){
var data = {product: Products.findOne({_id:objectId(this.params._id)})}
return data;
},
waitOn:function(){
return Meteor.subscribe('Products',this.params._id);
},
yieldTemplates: {'product': {to: 'mainArea'}},
});
I need a way to tell the router or template to reset the html
One solution is to set up an autorun in the template's onRendered function that looks for changes to the URL parameters and the resets the template as needed. Something like this:
Template.myTemplate.onRendered(function() {
var controller = Router.current()
this.autorun(function() {
var params = controller.getParams() // Reactive
// Clear up your drag interface here
});
});
By accessing controller.getParams() (the route controllers reactive parameter list) the outrun will be called when you move between routes on the same template.
Is there a way to set a reactive layout in meteor with iron router?
For example:
Router.configure({
loadingTemplate: 'loading',
layoutTemplate: Session.get('fullscreen') ? 'layoutFull' : 'layout'
});
Then a link in both layouts with:
Toggle Fullscreen
And then in both layouts something like this:
Template.layoutFull.events({
'click [data-action=toggleFullscreen]': function() {
Session.set('fullscreen', !Session.get('fullscreen'));
}
});
Template.layout.events({
'click [data-action=toggleFullscreen]': function() {
Session.set('fullscreen', !Session.get('fullscreen'));
}
});
The issue I'm running into is Router.configure isn't setting layoutTemplate reactively. Is there a way to do this so it affects all routes?
It has to be a function to be reactive:
layoutTemplate: function(){
return Session.get('fullscreen') ? 'layoutFull' : 'layout'
}
Also, why two functions?
You need just one since this is the negation of clicked Session
I have a tabs with four tab, each has a route with same controller.
All four tabs share the same data, menu, but use different part of the data.
Every time I click a tab, will it do a subscribe to the server?
For example, the first time I click tab1, it will contact server and get the data menu, then I click tab2, will it contact server again to fetch data menu even I have already gotten the data?
If so, how can I avoid this? Maybe I should redesign the code, is there any good ideas?
MenuController = RouteController.extend({
layoutTemplate: 'menuLayout',
waitOn: function () { return Meteor.subscribe('menu', this.params._id); },
data: function () { return Menu.findOne({_id: this.params._id}) },
});
this.route('/menu/tab1', {
name: 'menu.tab1',
template: 'MenuTab1',
controller: MenuController,
});
this.route('/menu/tab2', {
name: 'menu.tab2',
template: 'MenuTab2',
controller: MenuController,
});
this.route('/menu/tab3', {
name: 'menu.tab3',
template: 'MenuTab3',
controller: MenuController,
});
this.route('/menu/tab4', {
name: 'menu.tab4',
template: 'MenuTab4',
controller: MenuController,
});
This has changed somewhat as IR has matured. I believe in the current implementation, if you change between routes which make the same subscription with the same parameters, the subscription will not be stopped and started again. In other words, switching between tabs should not start and stop the subscription (assuming this.params._id remains constant).
You can prove (or disprove) this by adding a console.log('here') to the first line of your menu publisher. When you switch tabs, check the command-line console. If 'here' is printed only once, you have the desired outcome.
Regardless of the outcome, subs-manager is the generally accepted solution for caching subscriptions between routes.
I've got a template that has an intentional delay in it using http://deelay.me so I can test a slow server.
<template name="aboutPage">
<img src="http://deelay.me/2000/http://i.telegraph.co.uk/multimedia/archive/02830/cat_2830677b.jpg">
</template>
On my router page:
Router.configure
layoutTemplate: 'layout'
loadingTemplate: 'loading'
Router.route '/', name: 'homePage'
Router.route '/about', name: 'aboutPage'
loading template:
<template name="loading">
{{> spinner}}
</template>
For some reason, when I hit the About page, I get a missing image icon as the image loads. Am I missing something?
I made it works with this.
Router.route('/about', {
name: 'about',
data: function() {
if(this.ready()){
this.render()
}else{
this.render('loading')
}
}
});
Take a look, here we ensure that the all data on template is ready, if not we render the 'loading' template.
That works for me
I suggest you checking this package: https://atmospherejs.com/mrt/iron-router-progress
It let's you delay the progress from showing up on fast routes.
Router.configure
progressDelay : 100
Regarding the "missing image icon", I tried to reproduce the situation but I couldn't. However, I noticed that using the deelay.me technic won't work for testing the loading between routes. That's because aboutPage is already loaded when the image request starts. Therefore, the loading spinner already disappeared.
Check this repo por a simple example that actually tracks the image loading: https://github.com/humberaquino/meteor-imageloading-example
I hope this helps :)
I'm working on a survey/wizard type of meteor application.
The interface will only have two navigation buttons, who's caption/value will be determined dynamically based on whatever step a given user is currently at.
My question is: what markup syntax should I use within each of these two button's definitions in order to direct the Iron Router to change the route. Another words, where in the button definition should I put this: this.redirect('/anotherpath') ?
If you have a button in your template. If you are using a hrefs check answer from f3rland.
html:
<button #id="mybutton>m<Button</button>
you can catch the buttonpress event with javascript
js
Template.myTemplate.events({
'click #myButton': function(event, template) {
event.preventDefault();
Router.go('anotherpath');
}
});
The router should look like:
Router.map(function() {
this.route('anotherpath', {
path: '/',
layoutTemplate: 'myLayout',
controller: myController
});
});
I suggest you to use Iron-Router pathFor helper in your template
{{buttonText}}
That will redirect the user to the corresponding page/template.
You should also take a look at new blaze pattern to define custom block helper
Edit:
You could also use a custom helper for dynamic route as mentioned here
UI.registerHelper("_foo", function fooHelper() {
var templateName = figureOutNameDynamically(this.context.criticalInfo);
return Template[templateName];
});
<template name="foo">
{{> _foo context=.. atts=this}}
</template>
you can do this/change the route by using the action option which will automatically cal this.render().
you can do it yourself by calling the action function but I guess it is better to use onBeforeAction/after hooks