我目前在Meteor中遇到了一个集合插入问题。我调用一个方法将一个新项插入到一个集合中。服务器数据库显示新项目,但客户端没有该集合的记录。我发现如果我刷新页面,我的模板引用该集合就会填充并运行。
以下是插入位于'lib / collections / items.js'
的项目的方法Items = new Mongo.Collection("items");
Meteor.methods({
addItem: function (text) {
if (! Meteor.userId()){
throw new Meteor.Error("not-authorized");
}
console.log(text);
console.log(Meteor.userId());
console.log(Meteor.user().username);
console.log(Meteor.user().household);
Items.insert({
text: text,
createdAt: new Date(), //current time
owner: Meteor.userId(),
username: Meteor.user().username,
household: Meteor.user().household
});
},
以下是位于'/server/main.js'
的项目的服务器发布Meteor.publish("items", function(){
if(typeof Meteor.users.findOne({'_id': this.userId}) === 'undefined') return null;
return Items.find( {household : Meteor.users.findOne({'_id': this.userId}).household});
});
以下是调用位于'client / main.js'
的方法的代码Template.body.events({
"submit .new-task": function (event) {
// This function is called when the new task form is submitted
var text = event.target.text.value;
text = text.trim();
if(text)//Check for non-null, non-empty
{
text = capitalizeEachWord(text);
console.log(text);
Meteor.call("addItem",text);
}
//Clear form
event.target.text.value = "";
//Prevent default form submit
return false;
},
以下是查询集合的位置,以显示在'client / templates / itemList.js'的模板中
Template.itemList.helpers({
items: function() {
console.log('Trying to subscribe');
return Items.find({}, {sort : {checked: 1, createdAt: -1}});
}
我刚开始学习Meteor。我感谢任何帮助!
修改
感谢您的回复,
我已尝试过这些建议并仍然得到相同的结果。我尝试过将用户与家庭联系起来的不同方式,但仍然存在同样的问题。我可以从客户端插入一个项目,它存在于服务器端,但它在客户端不存在。我敢肯定我在这里缺少一些小东西,但对于我的生活,却找不到它。
我知道这是一个巨大的信息转储,但这是我更新的源代码(仍然产生相同的问题)和日志。我试图把我所知道的一切都放在这个问题上。谢谢你的帮助!我刚刚开始使用Meteor,我知道没有人在开发它,所以现在排除故障有点困难。
客户特定代码
位于'client / main.js'
Template.body.helpers({
householdId: function() {
//return Meteor.users.findOne({'_id': Meteor.userId()}).household;
if(Meteor.userId() &&
Households.findOne({users : {$regex : new RegExp(Meteor.userId())}}))
{
console.log('Trying to get id');
return Households.findOne({users : {$regex : new RegExp(Meteor.userId())}})._id;
}
}
});
Template.body.events({
"submit .new-task": function (event) {
// This function is called when the new task form is submitted
var text = event.target.text.value;
text = text.trim();
if(text)//Check for non-null, non-empty
{
text = capitalizeEachWord(text);
console.log(text);
Meteor.call("addItem",text);
}
//Clear form
event.target.text.value = "";
//Prevent default form submit
return false;
},
"submit .new-household": function (event) {
// This function is called when the new task form is submitted
var insertedId;
var text = event.target.householdName.value;
text = text.trim();
if(text)//Check for non-null, non-empty
{
text = capitalizeEachWord(text);
Meteor.call("createHousehold", text);
}
//Prevent default form submit
return false;
}
});
Accounts.ui.config({
passwordSignupFields: "USERNAME_ONLY",
});
订阅位于'client / application.js'
的我的馆藏的代码//Sub to our collections
Meteor.subscribe('households');
Meteor.subscribe('items');
代码迭代显示位于'client / templates / itemList.js'的项目
Template.itemList.helpers({
items: function() {
console.log('Trying to subscribe');
return Items.find(
{
household : Households.findOne( {users : {$regex : new RegExp(this.userId)}})._id
}
, {sort : {checked: 1, createdAt: -1}});
},
householdId: function() {
//return Meteor.users.findOne({'_id': Meteor.userId()}).household;
if(Meteor.userId())
{
console.log('Trying to get id from ');
return Households.findOne({users : {$regex : new RegExp(Meteor.userId())}})._id;
}
}
});
收集代码
家庭收集代码位于'lib / collections / households.js'
Households = new Mongo.Collection("households");
Meteor.methods({
createHousehold: function(text) {
var insertedId;
insertedId = Households.insert({
householdName: text,
createdAt: new Date(), //current time
users: this.userId
});
}//Add user in the future
});
项目集合代码位于'lib / collections / items.js'
Items = new Mongo.Collection("items");
Meteor.methods({
addItem: function (text) {
if (! Meteor.userId()){
throw new Meteor.Error("not-authorized");
}
console.log('Inserting item')
console.log('Item : ' + text);
console.log('UserId : ' + Meteor.userId());
console.log('Username : ' + Meteor.user().username);
console.log('Household : ' + Households.findOne( {users : {$regex : new RegExp(Meteor.userId())}})._id);
Items.insert({
text: text,
createdAt: new Date(), //current time
owner: Meteor.userId(),
username: Meteor.user().username,
household: Households.findOne( {users : {$regex : new RegExp(Meteor.userId())}})._id
});
return true;
},
deleteItem: function (itemId) {
Items.remove(itemId);
},
setChecked: function(itemId, setChecked) {
Items.update(itemId, { $set: {checked: setChecked}});
}
});
服务器代码
服务器代码位于'server / main.js'
Meteor.publish("households", function(){
console.log('Trying to subscribe');
console.log(this.userId);
if(this.userId)
{
//var query = { users : new RegExp("/"+this.userId+"/")};
//console.log(Households.findOne( query ));
console.log(Households.findOne( {users : {$regex : new RegExp(this.userId)}}));
return Households.find( {users : {$regex : new RegExp(this.userId)}});
}
else
{
console.log('Too early');
return null;
}
});
Meteor.publish("items", function(){
console.log('Trying to get items');
if(!this.userId ||
!Households.findOne( {users : {$regex : new RegExp(this.userId)}}))
{
console.log('Returning null');
return null;
}
console.log(Items.findOne( {household : Households.findOne( {users : {$regex : new RegExp(this.userId)}}) }));
console.log(this.userId);
return Items.find( {household : Households.findOne( {users : {$regex : new RegExp(this.userId)}})._id });
});
日志
如果我使用meteor在localhost上启动该站点。页面出现时(没有用户登录),这是服务器控制台输出:
=> App running at: http://localhost:3000/
I20141209-10:26:50.719(-5)? Trying to subscribe
I20141209-10:26:50.766(-5)? null
I20141209-10:26:50.766(-5)? Too early
I20141209-10:26:50.766(-5)? Trying to get items
I20141209-10:26:50.767(-5)? Returning null
接下来,我成功创建了一个用户帐户(使用accounts-ui / accounts-password包)。这是该点的输出。
I20141209-10:31:59.562(-5)? Trying to subscribe
I20141209-10:31:59.565(-5)? null
I20141209-10:31:59.566(-5)? Too early
I20141209-10:31:59.566(-5)? Trying to get items
I20141209-10:31:59.566(-5)? Returning null
I20141209-10:32:16.145(-5)? Trying to subscribe
I20141209-10:32:16.145(-5)? 8Skhof4jL2pSguT8Q
I20141209-10:32:16.146(-5)? undefined
I20141209-10:32:16.147(-5)? Trying to get items
I20141209-10:32:16.148(-5)? Returning null
接下来,我使用.new-household表单创建一个家庭。此时服务器上没有新输出,但这是客户端的输出:
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
itemList.js?a224bda493b90eb94bff9b88b48bb22eaa8aefe1:3 Trying to subscribe
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:7 Trying to get id
itemList.js?a224bda493b90eb94bff9b88b48bb22eaa8aefe1:3 Trying to subscribe
此时我使用.new-task表单添加一个项目。任务显示在屏幕上闪烁然后消失。这是此时的服务器输出:
I20141209-10:37:09.171(-5)? Inserting item
I20141209-10:37:09.172(-5)? Item : Beans
I20141209-10:37:09.172(-5)? UserId : 8Skhof4jL2pSguT8Q
I20141209-10:37:09.172(-5)? Username : pedro
I20141209-10:37:09.173(-5)? Household : M5NckT6ndqhRKCeWo
此时是客户端输出:
main.js?ba2ac06f3ff7f471a7fa97093ac9ed5c01e0c8cd:21 Beans
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:8 Inserting item
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:9 Item : Beans
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:10 UserId : 8Skhof4jL2pSguT8Q
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:11 Username : pedro
items.js?2ca606d1e71e2e55d91421d37f060bd5d8db98fe:12 Household : M5NckT6ndqhRKCeWo
此时项目存在于服务器数据库中,但如果我使用chrome中的Web控制台,则执行命令Items.findOne();它返回undefined。
答案 0 :(得分:0)
可能会有更多内容,但我无法看到您在客户端包含Meteor.subscribe("items")
的位置,因为这会将记录从服务器上的发布传递到客户端
同样在您的发布中,您可以使用
if (this.userId) {
//do stuff logged in
} else {
this.stop();
}
而不是选择用户ID的Meteor.user()
记录来检测客户端是否已登录。
答案 1 :(得分:0)
您的出版物:
Meteor.publish("items", function(){
if(user = Meteor.user()){
return Items.find( {household : user.household});
}
else{
this.ready();
}
});
你的帮手:
Template.itemList.helpers({
items: function() {
return Items.find({}, {sort : {checked: 1, createdAt: -1}});
}
});
您的订阅(客户端): Meteor.subscribe( “项目”);
如果你正在使用铁:路由器。在路线中,您可以直接定义您的助手和您的订阅,只需在模板中调用{{items}}:
Router.route('myRoute', function(){
this.render('myRouteTemplate');
}, {
path: '/myRoutePath',
waitOn: function(){
if(user = Meteor.user()) {
var subscriptions = [];
//
// Subscribe to your subscription
//===============================
subscriptions.push(Meteor.subscribe('items'));
return subscriptions;
}
},
data: function(){
var context;
if(this.ready()) {
if (user = Meteor.user()) {
context = {
items: Items.find( {household : user.household})
};
}
}
}
});
永远记住,当您发布杂志时,您需要一个订阅者流程。收藏也是一样。
干杯,
答案 2 :(得分:0)
我最终通过在我的应用程序中实现Iron Router并在呈现模板之前等待订阅准备就绪来解决此问题。我相信我之前的问题是某种竞争条件,但我对其具体情况并不乐观。无论哪种方式,我都对我的解决方案感到满意,因为它解决了我的问题,并且更好地构建了我的网站流程,而且我认为这更容易理解。