为什么Meteor在观察集合时会移除一个对象?

时间:2013-06-25 05:34:55

标签: meteor

背景

  • 我有“列表”和“产品”集合,产品属于列表
  • 列表包含描述,从中生成产品
  • 启动时,会创建一个对该访问者唯一的新列表
  • 列表ID存储在会话

我想要什么

我希望在List的描述发生变化时生成产品。

第一步是当更改当前访问者的列表时,我想要插入新产品。

我觉得我这样做完全错了......

问题

产品已插入,在浏览器中显示一瞬间,然后消失。它被Meteor删除了。

代码

Products = new Meteor.Collection("products");
Lists = new Meteor.Collection("lists");

if (Meteor.isClient) {
  Meteor.startup(function () {
    var my_list_id = Lists.insert({description: "Default list"});
    Session.set("my_list", my_list_id);      

    var observed = Lists.find({_id: my_list_id}).observe({
      changed: function (newDocument, oldDocument) {
        Products.insert({list: newDocument._id, name: newDocument.description});
      }
    });
  });

  toggleElement = function (elementName) {
    if(editedElementIs(elementName)) {
      var newListDescription = $('textarea').val();
      Lists.update(Session.get("my_list"), {description: newListDescription});
      setEditedElement("");
    } else {
      setEditedElement(elementName);
    }
  };


  // Including the rest in case I've misunderstood something. 
  // I don't see how any of this could cause the issue.
  setEditedElement = function (elementName) {
    return Session.set("edited_element", elementName);
  };

  editedElementIs = function (elementName) {
    return Session.get("edited_element") == elementName;
  };

  Handlebars.registerHelper('editedElementIs', editedElementIs);

  Handlebars.registerHelper('products', function() {
    return Products.find({list: Session.get("my_list")});
  });

  Template.list_form.listDescription = function () {
    return Lists.findOne({_id: Session.get("my_list")}).description;
  };

  Template.adminbar.events({
    'click a#editlist' : function () {
      toggleElement("list");
    },
    'click a#editsidebar' : function () {
      toggleElement("sidebar");
    }
  });
}

if (Meteor.isServer) {
  Meteor.startup(function () {
  });
}

我尝试过什么

显然,我可以这样做:

if(editedElementIs(elementName)) {
  var newListDescription = $('textarea').val();
  Products.insert({list: Session.get("my_list"), name: newListDescription});
  Lists.update(Session.get("my_list"), {description: newListDescription});
  ...

但那是我写的笨拙的更新代码,我想在观察者中找到它。

看起来该产品已被删除。因此,我观察到产品何时被移除:

Products.find({list:my_list_id}).observe({
  removed: function (oldDocument) {
    throw error("wow");
    console.log("Removed Product" + oldDocument);
  }
})

并在插入产品后立即调用此观察者。

我得到了堆栈跟踪:

at Object.Products.find.observe.removed (http://localhost:3000/ListyMeteor.js?2d867b7481df6389658be864b54d864151e87da5:22:15)
    at Object.cursor.observeChanges.removed (http://localhost:3000/packages/minimongo/minimongo.js?daa88dc39d67b40b11d6d6809d72361f9ef6a760:909:52)
    at http://localhost:3000/packages/minimongo/minimongo.js?daa88dc39d67b40b11d6d6809d72361f9ef6a760:275:15
    at _.extend.runTask (http://localhost:3000/packages/meteor/fiber_stubs_client.js?52687e0196bc1d3184ae5ea434a8859275702d94:30:11)
    at _.extend.flush (http://localhost:3000/packages/meteor/fiber_stubs_client.js?52687e0196bc1d3184ae5ea434a8859275702d94:58:10)
    at _.extend.drain (http://localhost:3000/packages/meteor/fiber_stubs_client.js?52687e0196bc1d3184ae5ea434a8859275702d94:66:12)
    at LocalCollection.remove (http://localhost:3000/packages/minimongo/minimongo.js?daa88dc39d67b40b11d6d6809d72361f9ef6a760:500:22)
    at Object.self._connection.registerStore.update (http://localhost:3000/packages/mongo-livedata/collection.js?682caa185350aa26968d4ffc274579a33922f0e6:109:32)
    at Object.store.(anonymous function) [as update] (http://localhost:3000/packages/livedata/livedata_connection.js?5d09753571656c685bb10c7970eebfbf23d35ef8:404:48)
    at http://localhost:3000/packages/livedata/livedata_connection.js?5d09753571656c685bb10c7970eebfbf23d35ef8:984:19 

看起来Meteor正在客户端刷新产品系列。

我显然误解了Meteor的工作原理。

关于为什么会发生这种情况的任何想法?

更新1

看起来这种情况正在发生,因为在观察者中调用了插入符号:

Why does meteor undo changes to collections nested in an observer method?

我确认后,我会在这里回复。

1 个答案:

答案 0 :(得分:0)

自动订阅是开启还是关闭?

如果您关闭自动订阅,可能会发生客户端更新服务器副本,然后更新服务器上的后续更新 - 未获取所有项目,因为它未订阅该集合。

最简单的检查方法是查询mongo db -

meteor mongo

如果您的产品已添加到文档中,请查询mongo db。

如果有,那么这是一个自动订阅问题 - 您必须在此处http://docs.meteor.com/#meteor_publish

创建发布(在服务器上)和订阅(在客户端上)方法