【问题标题】:Iron-Router checking document existence before route runsIron-Router 在路由运行前检查文档是否存在
【发布时间】:2015-02-20 05:26:51
【问题描述】:

我有一个基本的聊天室应用程序,您可以在其中从调用此方法的主页创建一个房间:

createNewRoom: function (){
    //Room containers unique ID for the object
    var room = Rooms.insert({
        createdAt: new Date()
    });
    return room;
},

房间的路线是这样的:

Router.route('/rooms/:_id', {
    name: 'room',
    template: 'chatRoom'
});

我正在尝试设置它,这样您就不能只输入任何随机 ID 并获得一个房间,它必须已经存在。所以我创造了这个铁路由器钩子:

var checkRoomExists = function() {
    var room = Rooms.findOne({_id : this.params._id});
    if(typeof(room) == "undefined"){
        Router.go('home');
    }
    else {
        this.next();
    }
}

Router.onBeforeAction(checkRoomExists, {
    only : ['room']
});

checkRoomExists 中的room 总是返回 undefined,即使我在其他地方使用相同的 _id 测试完全相同的语句并且房间存在。因此,如果我将链接发送给其他人,即使房间存在,它也会重定向。这是错误的钩子类型还是有更好的方法来完成这个?'

编辑一些附加信息: 这是第一次创建房间的代码:

Template.home.events({
    'click #create-room' : function(event){
        event.preventDefault();

        Meteor.call('createNewRoom', function(error, result){
            if (error){
                console.log(error);
            }else {
                Session.set("room_id", result);
                Router.go('room', {_id: result});
            }
        });
    }
});

如果我尝试在之后使用完整链接,例如 http://localhost:3000/rooms/eAAHcfwFutRFWHM56,它将不起作用。

【问题讨论】:

  • 这假设房间已发布给客户端。是这样吗?
  • 现在自动发布仍然安装,而我设置的东西是这样的。我可以进入控制台并执行:Rooms.findOne({_id: 's3iLE9gmnAcCHNuYM'}),它会返回一个对象,但它在那里不起作用。
  • 如果你console.log(room) 你得到了什么?一个东西?在checkRoomExists 函数上
  • 如果我从主页创建一个房间,它会返回一个对象,但如果我只是使用完整链接并在另一个浏览器中尝试:localhost:3000/rooms/eAAHcfwFutRFWHM56 它会返回 undefined。
  • 所以您想避免用户创建新房间(如果它们已经存在)?或在房间存在时访问它们?

标签: meteor iron-router


【解决方案1】:

我试图避免用户使用一些随机 ID,例如 localhost:3000/rooms/asdasd 如果具有该 ID 的房间还没有 存在。

如果你想这样做,你可以按照下一个。

在布局配置上添加这个。

Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  notFoundTemplate: 'notFound' //add the notFoundTemplate.
});

还有这个简单的onBeforeAction

Router.onBeforeAction('dataNotFound', {only: 'room'});

像这样创建一些示例模板。

<template name="notFound">
 <span> Dam this route don't exist <a href="/">go back to home</a>
</template>

选项

我不确定这是否仍然有效,但您可以在 routes.js js 的最后一个上定义它

this.route('notFound', {
  path: '*' //this will work like the notFoundTemplate
});

注意

如果你没有这样的布局模板使用。

Router.route('/rooms/:_id', {
    name: 'room',
    notFoundTemplate: 'authorNotFound',
    template: 'chatRoom'
});

【讨论】:

  • 您的示例中dataNotFound 来自哪里?
  • 默认自带铁路由
  • this dataNotFound不仅在rout不存在时返回true,如果数据对象返回null,undefined也返回true
  • 但是如果默认提供,我在哪里定义它使用的数据对象?我不确定我是否理解
  • 看看Rooms collection 中是否有 10 个对象,那么您将有 10 个可用路由,好吗?那么如果有人输入localhost:300:/rooms/123abc 实际上这条路线不存在会发生什么?但这实际上是一条有效的路线,对吗?但是123abc 它不是_id 标识符,因此路由不会指向任何地方,在这种情况下iron:routes 有一个名为dataNotFound 的特殊钩子,所以只需在routes.js 的底部调用它@Router.onBeforeAction('dataNotFound', {only: 'rooms'});
猜你喜欢
  • 2021-11-14
  • 2015-03-14
  • 2015-08-24
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 1970-01-01
相关资源
最近更新 更多