Iron Router - 取决于租户的条件路由
Iron Router - Conditional routes depending on tenant
我正在开发一个多租户应用程序,我不确定如何有条件地加载路由。
我有:
var tenant = resolveTenant();
if (tenant === null) {
Router.configure({
layoutTemplate: 'main',
notFoundTemplate: 'not-found'
})
Router.route('home', {
path: '/'
})
Router.route('newClient', {
path: 'signup'
})
} else {
Router.configure({
layoutTemplate: 'storeMain',
notFoundTemplate: 'not-found'
})
Router.route('storeHome', {
path: '/'
})
}
因此,如果无法解决租户问题,请加载主站点。
这工作得很好,不是很漂亮,但很好。但是,问题是当租户不存在时。
案例:
- http://localhost/ - 加载主程序
- http://store1.localhost/ - 加载商店
- http://notastore.localhost/ - 加载非租户模板。
为此,我需要调用数据库。所以我将条件包装在一个带有回调的方法调用中:
Router.configure({
layoutTemplate: "loading"
});
var tenant = resolveTenant();
Meteor.call("tenant.exists", tenant, function(err, exists) {
if (tenant !== null && !exists) {
Router.configure({
layoutTemplate: 'noTenant'
})
Router.route('noTenant', {
path: '/'
})
} else if (tenant === null) {
Router.configure({
layoutTemplate: 'main',
notFoundTemplate: 'not-found'
})
Router.route('home', {
path: '/'
})
Router.route('newClient', {
path: 'signup'
})
} else {
Router.configure({
layoutTemplate: 'storeMain',
notFoundTemplate: 'not-found'
})
Router.route('storeHome', {
path: '/'
})
}
})
问题是,它不会在调用完成后从加载模板配置中移动。如果我删除加载模板路由,我会得到 iron router 登陆页面。
为了完成,这里是 "tenant.exists" 方法:
"tenant.exists": function(url){
if(url === null){
return false
}
return Tenants.find({"url": url}).count() > 0;
},
关于如何实现这一点有什么想法吗?
编辑
我确实尝试从客户端的方法调用和 运行 查询中删除条件。然而,计数总是在不应该返回 0 时返回。
if (tenant !== null && Tenants.find({"url": tenant}).count() === 0) {
Router.configure({
layoutTemplate: 'noTenant'
})
Router.route('noTenant', {
path: '/'
})
} else if (tenant === null) {
Router.configure({
layoutTemplate: 'main',
notFoundTemplate: 'not-found'
})
Router.route('home', {
path: '/'
})
Router.route('newClient', {
path: 'signup'
})
} else {
Router.configure({
layoutTemplate: 'storeMain',
notFoundTemplate: 'not-found'
})
Router.route('storeHome', {
path: '/'
})
}
请允许我提出一个更简单的方法,该方法还可以避免将所有租户的名称发布给每个客户端,同时还可以避免 Meteor.call()
:
的异步副作用
- 订阅租户订阅,将租户名称作为参数传递
- 在相应的发布中,只有return一个匹配的租户
- 在
onBeforeAction
处理程序中,查看是否有租户记录,如果有则继续,否则呈现适当的页面。
路由器:
var tenant = resolveTenant();
Router.route('/',{
name: 'storeHome',
onBeforeAction: function(){
if ( Tenants.findOne() ) this.next();
else if ( tenant ) this.render('noTenant');
else this.render('signup');
},
waitOn: function(){
return Meteor.subscribe('tenant', tenant);
}
});
服务器:
Meteor.publish('tenant',name,function(){
check(name,String);
return Tenants.find({ url: tenant });
});
取自模式here。
我正在开发一个多租户应用程序,我不确定如何有条件地加载路由。
我有:
var tenant = resolveTenant();
if (tenant === null) {
Router.configure({
layoutTemplate: 'main',
notFoundTemplate: 'not-found'
})
Router.route('home', {
path: '/'
})
Router.route('newClient', {
path: 'signup'
})
} else {
Router.configure({
layoutTemplate: 'storeMain',
notFoundTemplate: 'not-found'
})
Router.route('storeHome', {
path: '/'
})
}
因此,如果无法解决租户问题,请加载主站点。
这工作得很好,不是很漂亮,但很好。但是,问题是当租户不存在时。
案例:
- http://localhost/ - 加载主程序
- http://store1.localhost/ - 加载商店
- http://notastore.localhost/ - 加载非租户模板。
为此,我需要调用数据库。所以我将条件包装在一个带有回调的方法调用中:
Router.configure({
layoutTemplate: "loading"
});
var tenant = resolveTenant();
Meteor.call("tenant.exists", tenant, function(err, exists) {
if (tenant !== null && !exists) {
Router.configure({
layoutTemplate: 'noTenant'
})
Router.route('noTenant', {
path: '/'
})
} else if (tenant === null) {
Router.configure({
layoutTemplate: 'main',
notFoundTemplate: 'not-found'
})
Router.route('home', {
path: '/'
})
Router.route('newClient', {
path: 'signup'
})
} else {
Router.configure({
layoutTemplate: 'storeMain',
notFoundTemplate: 'not-found'
})
Router.route('storeHome', {
path: '/'
})
}
})
问题是,它不会在调用完成后从加载模板配置中移动。如果我删除加载模板路由,我会得到 iron router 登陆页面。
为了完成,这里是 "tenant.exists" 方法:
"tenant.exists": function(url){
if(url === null){
return false
}
return Tenants.find({"url": url}).count() > 0;
},
关于如何实现这一点有什么想法吗?
编辑
我确实尝试从客户端的方法调用和 运行 查询中删除条件。然而,计数总是在不应该返回 0 时返回。
if (tenant !== null && Tenants.find({"url": tenant}).count() === 0) {
Router.configure({
layoutTemplate: 'noTenant'
})
Router.route('noTenant', {
path: '/'
})
} else if (tenant === null) {
Router.configure({
layoutTemplate: 'main',
notFoundTemplate: 'not-found'
})
Router.route('home', {
path: '/'
})
Router.route('newClient', {
path: 'signup'
})
} else {
Router.configure({
layoutTemplate: 'storeMain',
notFoundTemplate: 'not-found'
})
Router.route('storeHome', {
path: '/'
})
}
请允许我提出一个更简单的方法,该方法还可以避免将所有租户的名称发布给每个客户端,同时还可以避免 Meteor.call()
:
- 订阅租户订阅,将租户名称作为参数传递
- 在相应的发布中,只有return一个匹配的租户
- 在
onBeforeAction
处理程序中,查看是否有租户记录,如果有则继续,否则呈现适当的页面。
路由器:
var tenant = resolveTenant();
Router.route('/',{
name: 'storeHome',
onBeforeAction: function(){
if ( Tenants.findOne() ) this.next();
else if ( tenant ) this.render('noTenant');
else this.render('signup');
},
waitOn: function(){
return Meteor.subscribe('tenant', tenant);
}
});
服务器:
Meteor.publish('tenant',name,function(){
check(name,String);
return Tenants.find({ url: tenant });
});
取自模式here。