需要帮助更新Router.js以升级到Meteor 1.0和iron:路由器包

时间:2015-01-09 07:34:13

标签: meteor iron-router

我正在从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');
                }
            }
        });

    });
});

1 个答案:

答案 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);