我有一个具有多个条件的Meteor模板,并且在最初加载时我会看到一些条件视图的闪烁。
我正在使用铁路由器,我知道订阅,wait()和ready()选项,但其中一个问题是主条件isInstalled
取决于meteor.call回调到设置isInstalled变量,因此wait不依赖于订阅。那么我该如何解释这个用例?
<template name="adminLayout">
{{#if isInstalled}}
{{#if currentUser}}
{{> adminHeader}}
<br /><br />
<div class="row">
<div class="medium-3 columns">
{{> adminNav}}
</div>
<div class="medium-9 columns">
{{> yield}}
</div>
</div>
<div class="row">
<div class="medium-12 columns">
{{> adminFooter}}
</div>
</div>
{{else}}
{{> login}}
{{/if}}
{{else}}
{{> install}}
{{/if}}
</template>
这是我的模板助手,说明了我如何为isInstalled
Meteor.call('isInstalled', function (err, result) {
if (err) {
console.log(err);
}
Session.set('isInstalled', result);
});
Template.adminLayout.helpers({
isInstalled: function () {
return Session.get('isInstalled');
}
});
最后一条路线:
Router.route('/admin', function () {
this.layout('adminLayout');
this.render('dashboard');
});
答案 0 :(得分:0)
onBeforeAction钩子怎么样?当然你必须有/ login和/ install的其他路由,但我认为这将是更好的方法,因为用户应该能够浏览网址,如:
Router.onBeforeAction(function() {
if (!Meteor.userId()) {
Router.go('/login');
this.next();
} else {
if (/*check somehow if installed*/) {
this.next();
}else{
Router.go('/install');
this.next();
}
}
});
答案 1 :(得分:0)
事实证明闪烁问题实际上是Meteor问题,而不是Iron Router问题,尽管铁路由器可以提供一种解决方法来使用其wait()和ready()方法来解决问题。
在我的特定情况下,我并不需要等待订阅,而是要求Meteor.call结果。为了实现这一点,我创建了一个匿名函数,它返回一个对象句柄,其中包含一个铁路由器可以理解的就绪方法,我稍后可以在路由逻辑中实现。
Sindis指导我朝着正确的方向前进,虽然这是一个不完整的解决方案。以下是我完成它的方法:
Router.onBeforeAction(function (params) {
var self = this;
if (params.url.match(/admin/)) {
this.wait(function(){
Meteor.call('isInstalled', function (err, result) {
Session.set('installationCheck', true);
Session.set('isInstalled', result);
});
return {
ready: function () {
return Session.get('installationCheck');
self.next();
}
}
});
if (this.ready()) {
if (Session.get('isInstalled')) {
this.next();
} else if(Session.get('isInstalled') === false) {
console.log('go to install!');
this.render('install');
}
}
} else {
this.next();
}
});
这是一个更通用的模式,允许您根据异步条件设置路由
Router.onBeforeAction(function (params) {
var self = this;
this.wait(function(){
Meteor.call('someMethod', function (err, result) {
Session.set('someMethodCalled', true);
// do whatever with result...
Session.set('someCondition', true);
});
return {
ready: function () {
return Session.get('someMethodCalled');
self.next();
}
}
});
if (this.ready()) {
if (Session.get('someCondition')) {
this.next();
} else if(Session.get('someCondition') === false) { // important to be explicit ===
this.render('someSpecificRoute');
}
}
});