为什么我的测试集合没有更新?

时间:2013-01-06 16:03:57

标签: meteor

我正在自动订阅客户端上的一个集合。我的代码如下。我希望客户端有更新的信息,但它永远不会更新。除非我刷新页面,否则此问题会在按钮永远不会被消息替换。

实际上,我为“测试”提供了一份文件。集合应该在客户端上将其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());
    },
  });
  }

2 个答案:

答案 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()方法的右大括号后面的逗号。但据我所知,在运行测试时没有任何负面影响。