ユーザーがログインしていない場合にユーザーをログインページにリダイレクトするという一般的なニーズと戦っています(Windows7のMeteorv0.8.0)。
Stackoverflowについても同様の質問がいくつかありますが、私には答えがないようです。
動作しない#1:render()
ドキュメント から:
_onBeforeAction: function () {
if (!Meteor.user()) {
// render the login template but keep the url in the browser the same
this.render('login');
// stop the rest of the before hooks and the action function
this.stop();
}
},
_
ここで2つの問題:
1-ドキュメントが古くなっています。 this.stop()
関数はもうありません。述べたように ここ 、コードは次のようになります:
_onBeforeAction: function (pause) {
if (!Meteor.user()) {
// render the login template but keep the url in the browser the same
this.render('login');
// stop the rest of the before hooks and the action function
pause();
}
},
_
2-これは、ルートにlayoutTemplate
がない場合にのみ機能します。存在する場合、login
テンプレートはlayoutTemplate
の_{{>yield}}
_にレンダリングされます。これは通常、ログインページに必要なものではありません。
機能しない#2:Router.go()またはthis.redirect()
ログインページのルートを定義するのは自然な方法のように思えます。その後、次のことができます。
_Router.onBeforeAction(function(pause) {
if (!Meteor.user()) {
pause();
Router.go('\login');
}
}, {except: ['login']});
_
または:
_Router.onBeforeAction(function() {
if (!Meteor.user())
this.redirect('\login');
}, {except: ['login']});
_
しかし、奇妙なことに、元のルート(リダイレクト前)にlayoutTemplate
がある場合は、まだ問題があります。_/login
_テンプレートは_{{yield}}
_内にレンダリングされます。これも通常必要なものではありません(_/login
_テンプレートにはlayoutTemplate
が定義されていないため、間違いなく期待したものではありません)。
私はこれを部分的に解決する方法を見つけました:
_Router.onBeforeAction(function() {
if (!Meteor.user()) {
var that = this;
setTimeout(function() { that.redirect('\login'); }, 0);
}
}, {except: ['login']});
_
_/login
_テンプレートが表示される前に、元のルートのlayoutTemplate
が一時的に点滅することを除いて、_/login
_テンプレートはクリーンページとしてレンダリングされます。
これと同じ問題がありますか?
OK、ルートのレンダリング関数はテンプレートを現在のレイアウトにレンダリングするだけのようです。テンプレートを別のレイアウトにレンダリングするには、this.setLayout('templateName')
を呼び出す必要があります。 1つの注意点は、ログイン後にレイアウトを元に戻す必要があることです。
_onBeforeAction: function(pause) {
var routeName = this.route.name;
if (_.include(['login'], routeName))
return;
if (! Meteor.userId()) {
this.setLayout("newLayout");
this.render('login');
//if you have named yields it the login form
this.render('loginForm', {to:"formRegion"});
//and finally call the pause() to prevent further actions from running
pause();
}else{
this.setLayout(this.lookupLayoutTemplate());
}
}
_
ログインテンプレートがthis.setLayout('login')
を呼び出すことで必要なすべての場合、レイアウトとしてログインテンプレートをレンダリングすることもできます。
レイアウトテンプレートにifまたはunlessテンプレートヘルパーを配置できます。
{{#unless currentUser}}
{{> loginPage}}
{{else}}
{{> yield}}
{{/unless}}
これは、waitOnでのサブスクリプションの待機と関係があるようです。
以下は私のためにレイアウトレンダリング問題を解決します:
Router.onBeforeAction(function() {
if (!Meteor.user() && this.ready())
return this.redirect('/login');
}, {except: ['login']});
render()
からonBeforeAction()
の結果を返す必要があります。
_onBeforeAction: function () {
if (_.include(['login'], this.route.name)){
return;
}
if (!Meteor.userId()) {
return this.render('login');
}
}
_
また、Meteor.user()
をMeteor.userId()
に変更したことに注意してください。これにより、現在のユーザーのドキュメントが変更されるたびにフックが再実行されなくなります。
Meteor 0.8.3で私は動作します:
Router.onBeforeAction(function () {
if (_.include(['formLogin'], this.route.name)){
return;
}
if (!Meteor.userId()) {
this.redirect('formLogin');
return;
}
});