我正在自动订阅客户端上的一个集合。我的代码如下。我希望客户端有更新的信息,但它永远不会更新。除非我刷新页面,否则此问题会在按钮永远不会被消息替换。
实际上,我为“测试”提供了一份文件。集合应该在客户端上将其testCount属性更新为1,但除非我刷新页面,否则它永远不会发生。它不应该更新吗?
未安装自动发布包。
此时我确信Meteor中存在一个错误,或者我不了解一些基本的错误。我即将安装一个开发版本的meteor.js并想出来或者只是放弃,直到Meteor.js可能真的有效。 :P
我的控制台日志:
Tests updated!
checking test
no test
Tests updated! Object {_id: "ea9f6002-74c7-4f37-9f10-0167b3b6f65a", testCount: 0}
checking test result
test.testCount 0
我的服务器日志:
$ meteor reset;meteor
Project reset.
[[[[[ ~/Dropbox/projects/sphela-game/sphela ]]]]]
Running on: http://localhost:3000/
inserting new test
Connecting test, getting initial data.
Test added do nothing { testCount: 0, _id: 'ea9f6002-74c7-4f37-9f10-0167b3b6f65a' }
Connecting test, getting initial data.
Test added do nothing { testCount: 0, _id: 'ea9f6002-74c7-4f37-9f10-0167b3b6f65a' }
Running test.
Updating test to 1.
Test ran. { testCount: 1, _id: 'ea9f6002-74c7-4f37-9f10-0167b3b6f65a' }
Test added do nothing { testCount: 1, _id: 'ea9f6002-74c7-4f37-9f10-0167b3b6f65a' }
我的HTML:
<head> <title>Testing counts.</title> </head>
<body> {{> app}} </body>
<template name="app">
{{#if testSuccess}}
<h1>Test complete.</h1>
{{else}}
<button class="btn run-test">Run Test</button>
{{/if}}
</template>
我的JavaScript:
var Tests = new Meteor.Collection('tests');
if (Meteor.isClient) {
Meteor.startup(function() {
Session.set('testCount', 0)
Meteor.subscribe('connect');
});
Template.app.testSuccess = function() {
var test;
console.log('checking test result');
test = Tests.findOne();
if (!test) {
console.log('no test', test);
return false;
}
console.log('test.testCount', test.testCount);
return test.testCount > 0;
};
Template.app.events({
'click .run-test': runTest
});
function runTest(event) {
Meteor.call('runTest');
Session.set('testCount', 1);
}
Meteor.autorun(function() {
console.log('Tests updated!', Tests.findOne());
});
Meteor.autosubscribe(function() {
Meteor.subscribe('test-results', Session.get('testCount'));
});
}
if (Meteor.isServer) {
Meteor.startup(function() {
test = Tests.findOne({})
if (!test) {
test = {
testCount: 0
};
console.log('inserting new test');
test._id = Tests.insert(test);
} else {
console.log('startup reset');
test.testCount = 0;
Tests.update({_id:test._id}, test);
}
});
Meteor.publish('connect', function() {
var test_;
console.log('Connecting test, getting initial data.');
test_ = Tests.findOne({});
this.set('tests', test_._id, test_);
this.complete();
this.flush();
});
Meteor.publish('test-results', function(test) {
var handle;
handle = Tests.find({testCount: test}).observe({
changed: _.bind(function(test) {
console.log('Test changed', test._id, test.testCount);
this.set('tests', test._id, test);
this.flush();
}, this),
added: _.bind(function(test) {
console.log('Test added do nothing', test);
this.flush();
}, this)
});
this.complete();
this.flush();
this.onStop(function() {
handle.stop();
});
});
Meteor.methods({
runTest: function() {
var test;
console.log('Running test.');
test = Tests.findOne({});
test.testCount = 1;
console.log('Updating test to 1.');
Tests.update({_id: test._id}, test);
console.log('Test ran.', Tests.findOne());
},
});
}
答案 0 :(得分:3)
Naomi at meteor实际上在Google Group邮件列表中回答了我的问题。我的问题的要点是两个订阅/发布返回的冲突结果集,其中一个被忽略。
这实际上是在文件中,我错过了它:
如果多个订阅发送一个冲突的值 属性(相同的集合名称,文档ID和属性名称), 然后客户端上的值将是第一个订阅的值 客户端已激活。 (即使它不是第一个发送的 重复的属性。)
答案是不要在多个发布语句中返回相互冲突的结果集。我想避免发回相同的集合将有助于避免这种情况。
Naomi的完整答案低于[1]:
您所看到的行为会涉及编写自定义的一些细节 基于流星观察的出版商。
在我看来,你所看到的是如何产生的结果 多个订阅工作。这就是我认为正在发生的事情。 初始发布,服务器发送“在收集测试中,有一个 id为ea9f6002-74c7-4f37-9f10-0167b3b6f65a的对象,其中testCount为 0“会话变量计数为0,所以我们订阅测试结果在哪里 testCount是0.很棒,我们的本地版数据库已经存在 认为,所有订阅都同意,不需要进行任何更改。会议 变量计数更新为1.自动订阅进行订阅 测试结果是testCount是1.这意味着现在我们有两个 出版商:'connect'认为 ea9f6002-74c7-4f37-9f10-0167b3b6f65a的testCount为0(从不 得到更新,它怎么能有不同的想法? '测试结果'获得了 '添加'消息说ea9f6002-74c7-4f37-9f10-0167b3b6f65a有一个 testCount为1(当你运行一个新的观察时,你得到一个'添加'的消息 对于它的一切。稍后,您会收到“已更改”的消息 与光标相匹配的东西) - 但它没有做任何事情 添加了消息。看起来你期待一个“改变”的消息 代替。这里的总体结果是,因为我们有一个发布者 说ea9f6002-74c7-4f37-9f10-0167b3b6f65a的testCount为0, 客户认为,没有发布者说出任何其他相关信息 ea9f6002-74c7-4f37-9f10-0167b3b6f65a的testCount为0。
为了确保客户端看到testCount为非0,所有 声明文件的任何出版商 集合中的ea9f6002-74c7-4f37-9f10-0167b3b6f65a必须说明 testCount为非0,具有相应的set和flush调用。即使 你在添加的回调中发送了testCount为1的消息 观察,Meteor不保证客户看到的任何内容 当它订阅了两个与之相冲突的不同事物 文件的价值。
tl; dr version:观察游标获取添加的回调一次 观察集中的所有内容,无论何时第一次运行,即使是 项目已经在数据库中。当您有多个发布商时 在相同的文档中发布相同的密钥,客户端的版本 看到它将成为其中之一,但Meteor并不保证 如果出版商不同意哪一个。尽量不要允许多个 出版商不同意文件的内容,它只能 造成混乱。
[1] https://groups.google.com/forum/?fromgroups=#!topic/meteor-talk/KBhXK6a44kY
答案 1 :(得分:1)
这个问题表现在一个永远不会被a取代的按钮 消息,除非我刷新页面。
运行代码并单击按钮时,该按钮将替换为:
测试完成。
控制台显示:
checking test result testcount.js:10
test.testCount 1
我将您的javascript文件粘贴到我的IDE后发现了一个错误; runTest()
方法的右大括号后面的逗号。但据我所知,在运行测试时没有任何负面影响。