在Meteor应用程序中,发布到服务器上的集合的数据未显示在客户端中。
从默认的Meteor应用程序开始,我将默认的JavaScript文件更改为以下内容:
Test = new Mongo.Collection("test")
if (Meteor.isClient) {
Meteor.subscribe("test")
console.log(Test.find({}).fetch())
}
if (Meteor.isServer) {
Meteor.startup(function () {
Meteor.publish("test", function () {
var cursor = Test.find({})
var result = cursor.fetch()
console.log(result)
console.log(JSON.stringify(result))
return cursor
})
var selector = {}
var modifier = { key: "value" }
var options = {}
var callback = function (error, data) {
console.log("Test", error, data)
}
Test.upsert( selector, modifier, options, callback )
});
}
在服务器终端中,我可以看到文档已添加到Test集合中,并且该集合现在包含文档,但浏览器中console.log(Test.find({}).fetch())
的输出为[]
。
这是服务器的典型输出:
I20150924-14:38:59.313(-4)? Test null { numberAffected: 1 }
=> Meteor server restarted
I20150924-14:38:59.404(-4)? [ { _id: 'e3B6js9xq3pbspego', key: 'value' } ]
I20150924-14:38:59.405(-4)? [{"_id":"e3B6js9xq3pbspego","key":"value"}]
来自浏览器:
Navigated to http://localhost:3000/
[] mongoTest.js:5
我错过了什么?
答案 0 :(得分:1)
这是预期的,因为subscribe
不会阻止浏览器的执行。订阅开始后,Test.find()
在文档到达客户端之前执行。这是一个应该打印结果的实现:
if (Meteor.isClient) {
Meteor.subscribe('test', function() {
console.log(Test.find({}).fetch());
});
}
更强大的解决方案是使用autorun
,因为它可以避免添加第一个文档的任何竞争条件:
var handle = Meteor.subscribe('test');
Tracker.autorun(function() {
if (handle.ready())
console.log(Test.find({}).fetch());
});
推荐阅读:common mistakes的“订阅不会阻止”部分。
答案 1 :(得分:0)
将Tracker.autorun(...)
添加到客户端代码可以解决问题:
if (Meteor.isClient) {
Tracker.autorun(function () {
Meteor.subscribe("test")
console.log(Test.find({}).fetch())
})
}
浏览器控制台中的输出现在是:
Navigated to http://localhost:3000/
[] mongoTest.js:6
v [Object] mongoTest.js:6
> 0: Object
_id: "e3B6js9xq3pbspego"
key: "value"
length: 1
> __proto__: Array[0]
当客户端首次连接到服务器时,显然Test.find({}).fetch()
找到一个空集合,然后服务器有时间更新客户端上的集合。