2

「コンテンツ」と「ユニット」の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();
    }
  });
}

これは機能しますが、コンテンツ配列の最初の要素に属性「UnitName」を挿入する代わりに、新しい属性「content.0.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

警告:これから言うことは、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();});
};

別のテーブルと結合されるカスタムパブリッシャーを構築するには、追加されたコールバックを次のように変更します。

  • 追加されたオブジェクトに、参加するキーがあるかどうかを確認します
  • そのキーの他のコレクションで検索を実行します
  • フラッシュを呼び出す前に、公開する新しいキーと値を使用してサブスクリプションに設定されたコールを呼び出します。

上記は、必要なキーが常に他のテーブルにあることがわかっている場合にのみ十分であり、変更されないことに注意してください。変更される可能性がある場合は、2番目のテーブルにも監視を設定し、そこで変更されたメソッドのサブにキーを再設定する必要があります。

于 2012-12-14T00:42:29.213 に答える
4

this.setMeteor.publishはオブジェクトのトップレベルのプロパティでのみ機能します。つまり、Mongoスタイルの点線の属性はサポートされていません。配列setのまったく新しい値で呼び出す必要があります。contents

于 2012-12-14T01:05:34.517 に答える