我正在从Meteor 8.2更新到Meteor 1.0。我删除了所有旧的陨石包并安装了相关的流星包系统包。我不得不安装新的铁路由器包,我在流星运行的控制台中收到以下错误:
路线调度从未呈现过。您是否忘记在onBeforeAction中调用this.next()?
包的迁移说明说:“onBeforeAction钩子现在要求你调用this.next(),而不再使用pause()参数。”
我尝试通过从函数中删除pause
并在this.next();
语句后添加else
来关注该示例,但无济于事。
如何编辑我的路由器以便它使用新的onBeforeAction挂钩?此外,您可以从可能存在问题的迁移中调出的任何其他内容将非常感激。谢谢!
这是我的路由器文件:
/*****************************************************************************/
/* Client and Server Routes */
/*****************************************************************************/
// TODO: use these as per the Event Mind CLI tool.
//Router.configure({
// templateNameConverter: 'upperCamelCase',
// routeControllerNameConverter: 'upperCamelCase'
//});
Router.configure({
layoutTemplate: 'devLayout',
notFoundTemplate: 'devMain',
loadingTemplate: 'loading'
});
Router.onRun(function () {Session.set("waiting-on", null); });
Router.onBeforeAction(function() { Alerts.clearSeen(); });
var filters = {
nProgressHook: function (pause) {
// we're done waiting on all subs
if (this.ready()) {
NProgress.done();
} else {
NProgress.start();
pause(); // stop downstream funcs from running
}
}
};
Router.onBeforeAction(filters.nProgressHook);
Meteor.startup(function () {
Router.map(function () {
this.route('loading');
// reset password urls use hash fragments instead of url paths/query
// strings so that the reset password token is not sent over the wire
// on the http request
this.route('reset-password', {
template: 'devMain',
layoutTemplate: 'devLayout',
onRun: function () {
var token = this.params.hash;
Meteor.logout(function () {
Session.set("viewing-settings", true);
Session.set("set-password-token", token);
Session.set("settings-set-password", true);
// Session.set("enrolling", true) // do something special?
});
}
});
this.route('verify-email', {
template: 'devMain',
layoutTemplate: 'devLayout',
action: function () {
var self = this;
var token = self.params.hash;
Accounts.verifyEmail(token, function (err) {
if (!err) {
Alerts.throw({
message: "Your email address is now verified!",
type: "success", where: "main",
autoremove: 3000
});
Router.go('home');
} else {
Alerts.throw({
message: "Hmm, something went wrong: \""+err.reason +
"\". Try again?",
type: "danger", where: "main"
});
Session.set("viewing-settings", true);
Router.go('home');
}
});
}
});
this.route('leave-game', {
template: 'devMain',
layoutTemplate: 'devLayout',
action: function () {
var self = this;
var token = self.params.hash;
Meteor.call("leaveGameViaToken", token, function (err, res) {
if (!err) {
// Idempotently verify user's email,
// since they got the token via email.
Accounts.verifyEmail(token);
if (res.error) {
// e.g. "Leave-game link is for unknown game"
Alerts.throw({
message: res.error.reason, type: "danger", where: "main"
});
Router.go("home");
} else {
Alerts.throw({
message: "OK, you are no longer in this game.",
type: "success", where: res.gameId
});
Router.go("devDetail", {_id: res.gameId});
}
} else {
Alerts.throw({
message: "Hmm, something went wrong: \""+err.reason + "\".",
type: "danger", where: "main"
});
Router.go("home");
}
});
}
});
this.route('game-on', {
template: 'devMain',
layoutTemplate: 'devLayout',
action: function () {
var self = this;
var token = self.params.hash;
Meteor.call("gameOnViaToken", token, function (err, res) {
if (err || (res && res.error)) {
errorMessage = err ? "Hmm, something went wrong: \"" + err.reason + "\"." : res.error.reason;
Alerts.throw({
message: errorMessage, type: "danger", where: "main"
});
Router.go("home");
} else {
Alerts.throw({
message: "Woohoo! Players will be notified.",
type: "success", where: res.gameId
});
Router.go("devDetail", {_id: res.gameId, token: token });
}
});
}
});
this.route('cancel-game', {
template: 'devMain',
layoutTemplate: 'devLayout',
action: function () {
var self = this;
var token = self.params.hash;
Meteor.call("cancelGameViaToken", token, function (err, res) {
if (!err) {
Accounts.verifyEmail(token);
if (res.error) {
Alerts.throw({
message: res.error.reason, type: "danger", where: "main"
});
Router.go("home");
} else {
Alerts.throw({
message: "OK, your game is now cancelled, and players "
+ "will be notified.",
type: "success", where: "main"
});
Router.go("home");
}
} else {
Alerts.throw({
message: "Hmm, something went wrong: \""+err.reason + "\".",
type: "danger", where: "main"
});
Router.go("home");
}
});
}
});
// quite similar to 'leave-game' route
this.route('unsubscribe-all', {
template: 'devMain',
layoutTemplate: 'devLayout',
action: function () {
var self = this;
var token = self.params.hash;
Meteor.call("unsubscribeAllViaToken", token, function (err, res) {
if (!err) {
// Idempotently verify user's email,
// since they got the token via email.
Accounts.verifyEmail(token);
if (res.error) {
// e.g. "Token provided in link is not an unsubscribe-all token"
Alerts.throw({
message: res.error.reason, type: "danger", where: "main"
});
Router.go("home");
} else {
Alerts.throw({
message: "OK, you will no longer receive emails "
+ "from Push Pickup.",
type: "success", where: "main"
});
Router.go("home");
}
} else {
Alerts.throw({
message: "Hmm, something went wrong: \""+err.reason + "\".",
type: "danger", where: "main"
});
Router.go("home");
}
});
}
});
this.route('enroll-account', {
template: 'devMain',
layoutTemplate: 'devLayout',
onRun: function () {
var token = this.params.hash;
Meteor.logout(function () {
Session.set("viewing-settings", true);
Session.set("set-password-token", token);
Session.set("settings-set-password", true);
// Session.set("enrolling", true) // do something special?
});
}
});
// the home page. listing and searching for games
this.route('home', {
path: '/',
template: 'devMain',
layoutTemplate: 'devLayout'
});
// typical user interaction with a single game
this.route('devDetail', {
path: '/g/:_id/:token?',
layoutTemplate: 'devLayout',
onRun: function () {
Session.set("joined-game", null);
},
waitOn: function () {
return Meteor.subscribe('game', this.params._id);
},
onBeforeAction: function (pause) {
Session.set("soloGame", this.params._id);
},
data: function () {
var game = Games.findOne(this.params._id);
if (game) {
Session.set("gameExists", true);
}
return game;
},
action: function () {
var token = this.params.token;
if (Session.get("gameExists")) {
this.render();
} else {
Router.go('home');
Alerts.throw({
message: "Game not found",
type: "warning", where: "top"
});
}
if (token) {
Meteor.call("sendReminderEmailsViaToken", token, function (err, res) {
var errorMessage;
Accounts.verifyEmail(token);
if (err || (res && res.error)) {
errorMessage = err ? "Hmm, something went wrong: \"" + err.reason + "\"." : res.error.reason;
Alerts.throw({
message: errorMessage, type: "danger", where: "main"
});
Router.go("home");
}
});
}
},
onStop: function () {
Session.set("soloGame", null);
Session.set("gameExists", null);
}
});
this.route('devAddGame', {
path: '/addGame',
template: 'devEditableGame',
layoutTemplate: 'devLayout',
onRun: function () {
Session.set("selectedLocationPoint", null);
Session.set("newGameDay", null);
Session.set("newGameTime", null);
InviteList.remove({});
},
waitOn: function() {
Meteor.subscribe('recently-played');
},
data: function () {
return {
action: 'add',
title: 'Add game',
submit: 'Add game'
};
}
});
this.route('invitePreviousPlayers', {
path: 'invitePlayers',
template: 'invitePreviousPlayers',
layoutTemplate: 'devLayout'
});
this.route('devEditGame', {
path: '/editGame/:_id',
template: 'devEditableGame',
layoutTemplate: 'devLayout',
onRun: function () {
Session.set("selectedLocationPoint", null);
},
waitOn: function () {
return Meteor.subscribe('game', this.params._id);
},
onBeforeAction: function (pause) {
Session.set("soloGame", this.params._id);
},
data: function () {
return _.extend({
action: 'edit',
title: 'Edit game',
submit: 'Update game'
}, Games.findOne(this.params._id));
},
action: function () {
var self = this;
var user = Meteor.user();
var game = self.data();
if (user && user._id === game.creator.userId ||
user && user.admin) {
self.render();
} else {
Router.go('home');
}
}
});
this.route('adminView', {
path: '/admin',
onBeforeAction: function () {
var user = Meteor.user();
if (!user || !user.admin) {
this.render('home');
}
}
});
});
});
答案 0 :(得分:1)
新的onBeforeAction挂钩必须调用this.next();你必须在每个onBeforeAction中调用它。例如,新Iron Router中的管理路由如下所示:
Router.route('/admin', {
name: 'adminView',
onBeforeAction: function () {
var user = Meteor.user();
if (!user || !user.admin) {
this.render('home');
}
this.next();
}
});
用Router.route('/ path',options)替换Router.map中的所有this.route(...)并删除Router.map()
您的全球onBeforeAction将如下所示:
Router.onBeforeAction(function() {
Alerts.clearSeen();
this.next();
});
此外,您不需要在Meteor.startup(...)中包装路由。你可以删除它。
并且没有暂停参数,而不是暂停调用this.next()外部条件:
var filters = {
nProgressHook: function () {
// we're done waiting on all subs
if (this.ready()) {
NProgress.done();
} else {
NProgress.start();
}
this.next();
}
};
Router.onBeforeAction(filters.nProgressHook);