流星数据库延迟

时间:2013-01-26 00:53:22

标签: meteor

我的meteor目录由2个文件组成:

social.js:

Messages = new Meteor.Collection("messages");

if (Meteor.isServer) {
}

if (Meteor.isClient) {
    Template.temple.messages = function() {
        return Messages.find();  
    };

    Meteor.startup(function () {
            console.log('console startup: ' + Messages.find().count());
    });

    console.log('console normal: ' + Messages.find().count());

    var ali = function() {
        console.log('console normal: ' + Messages.find().count());
    };

    setTimeout(function() {
        console.log('console normal: ' + Messages.find().count());
    }, 2000);
    // The callback function is not called on the following line:
    Meteor.subscribe('messages',function(){alert('ALERT!');});
}

social.html:

<head>
<title>naber</title>
</head>

<body>
{{> temple}}
</body>

<template name = "temple">
{{#each messages}}
{{message}} <br />
{{/each}}
</template>

该集合仅在经过一段时间后才完全加载。如果我绕过setTimeout,我只能看到文件的真实数量。如何确保在数据库真正完全可用后执行我的函数?

3 个答案:

答案 0 :(得分:2)

Meteor.subscribe(NAME)Meteor.publish(NAME)配对。您的代码尝试订阅名为"messages"的内容,但您不会发布具有该名称的内容。

您获取数据的事实表明您使用的是默认的autopublish包(请参阅.meteor/packages进行检查),这意味着您无需显式发布或订阅数据。不幸的是,当自动发布的数据准备好(可能应该修复)时,无法获得回调。因此,如果您想这样做,您需要meteor remove autopublish并使用Meteor.publish发布您要发布的数据;那么,你实际上可以使用Meteor.subscribe回调。

答案 1 :(得分:1)

我通常会在加载订阅之前显示加载指示符。请参阅此示例:Meteorjs loading message

从服务器端发布集合:

if (Meteor.isServer) {
  Meteor.publish("messages", function () {
    return Messages.find(); // everything
  );
}

答案 2 :(得分:1)

由于Meteor的反应性如何工作,因此您需要设计一个应用程序状态,以便服务器尚未将数据发送到客户端。你可以称之为“加载”状态。

Template声明中,您必须始终检查您所依赖的数据是否可用。如果模板确实依赖于数据,则期望它首先呈现为空,然后在数据到达时更新,因为数据是反应性数据源。

使用您自己的函数,最好以这样的方式编写它们,使它们依赖于反应式数据源并使用Meteor.autorun之类的东西来确保在这些数据源发生变化时重新执行它们。

Meteor.startup内加载页面后,始终放置要运行的代码,否则在代码执行时甚至没有Meteor可用的风险。

以下是重写代码的方法:

Messages = new Meteor.Collection("messages");
if (Meteor.isClient){
  Meteor.startup(function() {
    // anything you need to do, like subscriptions 
  });
  Template.temple.loading = function() {
    return Messages.find().count === 0 ? "Loading..." : "";
  }
  Template.temple.messages = function() {
    var messages = Messages.find();
    if (messages.count() > 0) return messages;
  }
}

<template name="messages">
  {{loading}}
  {{#each messages}}
    {{message}}<br>
  {{/messages}}
</template>

如果您只是在客户端上使用Meteor.subscribe,则实际上不需要Messages.find()次对邮件进行调用。