Javascript 为什么这个路由逻辑没有找到已经创建的文档,而是创建新的、重复的文档?
当路由到特定URLJavascript 为什么这个路由逻辑没有找到已经创建的文档,而是创建新的、重复的文档?,javascript,mongodb,meteor,iron-router,Javascript,Mongodb,Meteor,Iron Router,当路由到特定URL/X时,我想将名为X的“频道”项插入Mongo.Collection,但仅当在数据库中找不到名为X的项时。否则,它应该从数据库中获取该项,并将其作为数据传递,以使用它呈现我的通道页面模板 Channels = new Meteor.Collection('channels'); Router.route('/:channelName', { name: 'channelPage', template: 'channelPage', data: function()
/X
时,我想将名为X
的“频道”项插入Mongo.Collection
,但仅当在数据库中找不到名为X
的项时。否则,它应该从数据库中获取该项,并将其作为数据
传递,以使用它呈现我的通道页面
模板
Channels = new Meteor.Collection('channels');
Router.route('/:channelName', {
name: 'channelPage',
template: 'channelPage',
data: function() {
var currentChannelName = this.params.channelName.toLowerCase();
var channelInDB = Channels.findOne({
name: currentChannelName
});
if (channelInDB === undefined) {
Channels.insert({
name: currentChannelName
});
return Channels.findOne({
name: currentChannelName
});
} else {
return channelInDB;
}
}
});
每次我转到/X
页面时,data
函数似乎运行两次。第一次(channelInDB==未定义)
为true
。即使集合中已经有一个带有{name:“X”}
的“通道”项。因此,每次我请求页面时,都会插入一个名为X
的新项目。还尝试在
onBeforeAction
hook中执行检查,但没有帮助。我遗漏了什么,如何解决这个问题
更新 我把
upsert
移动到Meteor.methods
我首先应该做的事情。我的代码现在如下所示:
Router.route('/:channelName', {
name: 'channelPage',
template: 'channelPage',
data: function() {
var currentChannelName = this.params.channelName.toLowerCase();
var channelId = Meteor.apply('callChannelPage', [currentChannelName], {
wait: true
});
console.log(channelId); //undefined
return channelId;
}
});
if (Meteor.isServer) {
Meteor.methods({
'callChannelPage': function(channelName) {
Channels.upsert({name: channelName}, {$set: {name: channelName}});
var result = Channels.findOne({name: channelName}, {fields: {_id: 1}});
return result._id;
}
});
}
我使用了Meteor.apply
和{wait:true}
选项,而不是Meteor.call
来等待响应,但在路由运行时它仍然返回未定义的
。我知道Meteor.method是有效的,因为当我使用
asyncCallback
运行调用时,它返回正确的ChannelId
Meteor.call('callChannelPage', currentChannelName,
function(error, results) {
console.log(results); //tfdaczfnZgwycFDtv
});
如何在路由器运行时获取它,以便我可以使用模板中的数据
解决方案
我当前的解决方案是仅基于channelname在channelPage.helper
中获取频道数据
Router.route('/:channelName', {
name: 'channelPage',
template: 'channelPage',
data: function() {
var channelName = this.params.channelName.toLowerCase();
Meteor.call('callChannelPage', channelName);
return {channelName: channelName};
}
});
//isClient
Template.channelPage.helpers({
'name': function() {
return this.channelName;
},
'channelId': function(){
return Channels.findOne({name: this.channelName})._id;
},
});
//isServer
Meteor.methods({
'callChannelPage': function(channelName) {
Channels.upsert({name: channelName}, {$set: {name: channelName}});
}
});
通过这种方式,模板呈现,来自集合的数据看起来有点延迟。这对我来说很好,但这是正确的方法吗?这只会在直接访问该URL时发生吗?或者当您使用Router.go('channelPage',{channelName:'X'})
时会发生这种情况吗?您的频道订阅是什么样子的?别忘了,只有当文档不存在时,您才能自动插入。这将为您节省一些代码。@challettRouter.go('channelPage',{channelName:'X'})
工作正常。但是我需要比channelName
更多的channelPage上的数据。我是否应该将每个URL路由到channelPage
并使用Template.channelPage.handers
获取数据?@Jahx您可以根据需要添加更多参数。但我不知道你的意思。能否将您对频道集合的订阅添加到您的问题中?在“路由器数据”功能中返回的任何内容都将在模板帮助程序中的下提供。除了返回数据中的对象之外,我没有尝试过返回任何东西。如何从助手处访问channelID?@challett此时我使用autopublish
和unsecure
软件包。我当前的解决方案是仅基于channelname在channelPage.helper
中获取频道数据。(见更新)