Meteor.js:客户端不订阅集合

时间:2012-07-11 18:54:57

标签: javascript node.js meteor

我为自己创建了一个小例子来测试Meteor的一些东西。但是现在看起来我无法订阅一个集合,我在服务器端发布了。我希望有人可以告诉我这个错误在哪里。

服务器/ model.js

Test = new Meteor.Collection("test");

  if (Test.find().count() < 1) {
    Test.insert({id: 1,
                 name: "test1"});

    Test.insert({id: 2,
                 name: "test2"});
  }

Meteor.publish('test', function () {
  return Test.find();
});

的客户机/ test.js

Meteor.subscribe("test");

Test = new Meteor.Collection("test");

Template.hello.test = function () {
  console.log(Test.find().count());//returns 0
  return Test.findOne();
}

Template.hello.events = {
  'click input' : function () {
    // template data, if any, is available in 'this'
    if (typeof console !== 'undefined')
      console.log("You pressed the button");
  }
};

的客户机/的test.html

<head>
  <title>test</title>
</head>

<body>
  {{> hello}}
</body>

<template name="hello">
  <h1>Hello World!</h1>
  {{#with test}}
    ID: {{id}}  Name: {{name}}
  {{/with}}
  <input type="button" value="Click" />
</template>

编辑1

我想更改对象测试,findOne()返回。让我们说添加一个包含两个数字(test.number1和test.number2)的平均值的属性avg。在我看来,这应该类似于以下代码。但是javascript不是同步的,所以这不起作用。

Template.hello.test = function () {
  var test = Test.findOne();
  test.avg = (test.number1 + test.number2) / 2;
  return test;
}

编辑2

这段代码对我有用。现在我必须重新思考为什么这个带有'if(test)'的解决方案只适用于我的原始项目中没有选择器的findOne()。

Template.hello.test = function () {
  var avg = 0, total = 0, cursor = Test.find(), count = cursor.count();
  cursor.forEach(function(e)
  {
    total += e.number;
  });
  avg = total / count;

  var test = Test.findOne({id: 1});
  if (test) {
    test.avg = avg;
  }

  return test;
}

2 个答案:

答案 0 :(得分:3)

客户端数据库用于复制数据的延迟可能会导致游标无法计算结果的情况。当模板在应用程序加载时立即呈现时,尤其会发生这种情况。

一种解决方法是在输入结果集时观察查询文档。因此,例如以下类似的东西恰好运作良好:

Meteor.subscribe("Coll");

var cursor = Coll.find();

cursor.observe({
  "added": function (doc) {
    ... something...
  }
})

答案 1 :(得分:0)

尝试使用{{#with test}}...{{/with}}语句包围{{#if}}...{{/if}}(因为在第一次数据推送test中没有idname字段):

<head>
  <title>test</title>
</head>

<body>
  {{> hello}}
</body>

<template name="hello">
  <h1>Hello World!</h1>
  {{#if test}}
    {{#with test}}
      ID: {{id}}  Name: {{name}}
    {{/with}}
  {{/if}}
  <input type="button" value="Click" />
</template>

结果:

Resulting page

更新

此代码执行所有记录中字段number的平均值的计算:

model.js:

Test = new Meteor.Collection("test");

Test.remove({});

if (Test.find().count() < 1) 
{
    Test.insert({id: 1,
                 name: "test1",
                 number: 13});

    Test.insert({id: 2,
                 name: "test2",
                 number: 75});
}

test.js

Test = new Meteor.Collection("test");

Template.hello.test = function () {
  var avg = 0, total = 0, cursor = Test.find(), count = cursor.count();
  cursor.forEach(function(e)
  {
    total += e.number;
  });
  avg = total / count;

  return { "obj": Test.findOne(), "avg": avg };
}

更新2

此代码段适用于我:

var test = Test.findOne(); 
if (test) 
{ 
    test.rnd = Math.random(); 
} 
return test; 

也许你应该尝试将赋值代码包装到if语句中?