MeteorJS ReactiveVar与数据库数据

时间:2015-09-15 09:02:59

标签: meteor

显然,我对ReactiveVar做错了,因为我不能按照我的预期让它工作。

我试图通过调用返回用户名列表的Meteor.call方法来设置ReactiveVar的值。但是当应用程序的另一部分中的用户名发生更改时,它不会更新。

我试过了两个:

Template.qastatistics.created = function () {
  this.trackUsernames = new ReactiveVar(false);
  var instance = Template.instance();
  Meteor.call('trackUsernames', function (err, data) {
    instance.trackUsernames.set(data);
  });
};

Template.qastatistics.helpers({
  users: function () {
  var usernames,
  instance = Template.instance();
  if (instance.trackUsernames.get() === false) {
    Meteor.call('trackUsernames', function (err, data) {
      instance.trackUsernames.set(data);
    });
  }
  usernames = instance.trackUsernames.get();
  ...

但是,当数据库中的这些更改时,两者都不会更新用户名列表。

这对ReactiveVars来说甚至是可能还是我完全误解了它们?

编辑:我提到的用户名不是来自Meteor.users集合,而是来自另一个包含用户名的集合的不同调用。

2 个答案:

答案 0 :(得分:2)

我将使用onCreated函数而不是定义created。这是一个更可扩展的,它是新的API。 created只是为了向后兼容而保持不变。

关于您的问题。你是对的,你似乎误解了ReactiveVar的所作所为。它们是反应性数据源。这意味着当您在某些myReactiveVar.get(又称反应计算)中调用Tracker.autorun时,只要调用myReactiveVar.set,计算就会重新运行。

你的第一部分是正确的。 Spacebars助手总是在自己的计算中运行。你错了的是认为方法调用是一种反应行为。这意味着,您可以致电trackUsernames并再次设置trackUsernames ReativeVar,模板中的值会自行更新。但是方法只运行一次。它没有做任何与反应性有关的事情。

方法调用仅传输一次数据。另一方面,当您发布一组文档(如所有用户)时,它们将动态更新。只要在发布的文档集中发生更改,它就会同步到客户端。 因此,一般而言,使用发布和订阅来反应性地同步数据会更好。如果你想使用同样的方法,你需要做一些轮询(所以你再次回到石器时代)。

实现您尝试执行的操作的最简单方法是使用Meteor.users.find().fetch()。正如它在the docs fetch中所说的那样,如果从被动计算中调用它,那么你将获取所有文档的依赖关系。

首先,您需要正确设置发布,以便用户可以看到其他用户的用户名。我会留给你的。然后你需要重新实现你的助手

Template.qastatistics.helpers({
  users: function () {
    var usernames = _.pluck(Meteor.users.find().fetch(), 'username');
...

答案 1 :(得分:0)

感谢@kyll的建议,我设法通过发布我需要的数据来获得我想要的东西:

服务器:

cope.publish.usernamesID = Random.id();
Meteor.publish("itemsusernames", function () {
    self = this;

    var initializing = true;
    var handle = Items.find().observeChanges({
        added: function (id) {
            !initializing && self.changed(
                "itemsusernames",
                cope.publish.usernamesID, 
                Items.distinct("p4User"));
        },
        changed: function (id) {
            !initializing && self.changed(
                "itemsusernames",
                cope.publish.usernamesID, 
                Items.distinct("p4User"));
        },
        removed: function (id) {
            !initializing && self.changed(
                "itemsusernames",
                cope.publish.usernamesID, 
                Items.distinct("p4User"));
        }
    });
    initializing = false;

    self.added("itemsusernames", cope.publish.usernamesID, Items.distinct("p4User"));
    self.ready();

    self.onStop(function () {
        handle.stop();
    });
});

客户端:

users: function () {
    var usernames = [],
        oUsernames = ItemsUsernames.find().fetch();

    if (!oUsernames[0]) return [];

    usernames = $.map(oUsernames[0], function (value, index) {
        if (!isNaN(index)) {
            return [value];
        }
    });
    ...

当然:ItemsUsernames = new Mongo.Collection("itemsusernames");