2

我有两个集合“内容”和“单元”。在内容集合中有一个字段“unitID”,它指的是单元集合。在流星发布功能中,我想添加所有新创建内容的单位类型名称:

Meteor.publish("contents", function () {
  var self = this;

  var handle = Contents.find().observe({
    changed: function(contentdoc, contentid) {
        var UnitName = Units.findOne({_id: contentdoc.unittypeid }, {fields: {type: 1}});

        self.set("contents", contentid, {'content.0.typename': UnitName});
        self.flush();
    }
  });
}

这可行,但它创建了一个新的属性“content.0.UnitName”,而不是在内容数组的第一个元素中插入属性“UnitName”:

[
    {
       _id:"50bba3ca8f3d1db27f000021",
       'content.0.UnitName':
       {
           _id:"509ff643f3a6690c9ca5ee59",
           type:"Drawer small"
       },
       content:
       [
           {
               unitID:"509ff643f3a6690c9ca5ee59",
               name: 'Content1'
           }
       ]
    }
]

我想要的是以下内容:

[
    {
       _id:"50bba3ca8f3d1db27f000021",          
       content:
       [
           {
               unitID:"509ff643f3a6690c9ca5ee59",
               name: 'Content1',
               UnitName:
               {
                    _id:"509ff643f3a6690c9ca5ee59",
                    type:"Drawer small"
                }
           }
       ]
    }
]

我究竟做错了什么?

4

2 回答 2

4

this.setwithinMeteor.publish仅适用于对象的顶级属性,这意味着它不支持 Mongo 样式的点属性。您必须使用数组set的整个新值进行调用。contents

于 2012-12-14T01:05:34.517 回答
4

警告:我要说的将在 Meteor 的未来版本中发生变化。我们目前正在彻底检查自定义发布者 API 以使其更易于使用,但会破坏向后兼容性。

那就是说...

看起来您正在尝试做的是将服务器端连接构建到已发布的集合“内容”中。在这里,作为参考,是发布游标的当前代码(从 0.5.2 开始)(当您的发布者返回游标对象时):

Cursor.prototype._publishCursor = function (sub) {
  var self = this;
  var collection = self._cursorDescription.collectionName;

  var observeHandle = self._observeUnordered({
    added: function (obj) {
      sub.set(collection, obj._id, obj);
      sub.flush();
    },
    changed: function (obj, oldObj) {
      var set = {};
      _.each(obj, function (v, k) {
        if (!_.isEqual(v, oldObj[k]))
          set[k] = v;
      });
      sub.set(collection, obj._id, set);
      var deadKeys = _.difference(_.keys(oldObj), _.keys(obj));
      sub.unset(collection, obj._id, deadKeys);
      sub.flush();
    },
    removed: function (oldObj) {
      sub.unset(collection, oldObj._id, _.keys(oldObj));
      sub.flush();
    }
  });

  // _observeUnordered only returns after the initial added callbacks have run.
  // mark subscription as completed.
  sub.complete();
  sub.flush();

  // register stop callback (expects lambda w/ no args).
  sub.onStop(function () {observeHandle.stop();});
};

要构建与另一个表连接的自定义发布者,请将添加的回调修改为:

  • 检查添加的对象是否具有您要加入的键
  • 在其他集合中查找该键
  • 在调用flush之前,使用您要发布的新键和值在您的订阅上调用set。

请注意,仅当您知道所需的键将始终在另一个表中并且它永远不会更改时,上述内容才足够。如果它可能会改变,你也必须在第二张桌子上设置一个观察,并在那里用改变的方法重新设置 sub 上的键。

于 2012-12-14T00:42:29.213 回答