Meteor:添加关联记录不起作用

时间:2016-06-04 15:38:07

标签: javascript mongodb meteor

我有PostsComments,我正在尝试构建用于使用React和Meteor为帖子添加评论的UI。当我提交评论时,新评论会出现,然后立即消失。当我刷新页面时,新评论就在那里。

Meteor.publish('post', function(postId) {
  return Posts.find(postId);
});

Meteor.publish('comments.forPost', function(postId) {
  const post = Posts.findOne(postId);
  return Comments.find({_id: { $in : post.comments } } );
});

Meteor.methods({
  'comments.insert'({ postId, content }) {
    check(postId, String);
    check(content, String);

    const commentId = Comments.insert({
      createdAt: new Date(),
      userId: this.userId,
      content,
    });

    Posts.update(postId, { $addToSet: { comments: commentId }});
});

在我的React组件中,我使用createContainer

export default createContainer((props) => {
  const id = props.params.id;
  const postHandle = Meteor.subscribe('post', id);
  const isLoading = !postHandle.ready();
  Meteor.subscribe('comments.forPost', id);
  const post = Posts.findOne(id);
  const comments = 
    isLoading ? [] : Comments.find({_id: { $in: post.comments } }).fetch();
  console.log(comments.length);
  return {
    comments,
    isLoading,
    question,
  };
}, PostShow);

我的console.log语句在添加注释后打印新长度,然后打印前一个数字。

1 个答案:

答案 0 :(得分:0)

这是因为在您的出版物中post仅被评估一次,因此您的光标不是"被动"从某种意义上说,当你comments更改时,它不会重新评估查询。

有几种方法可以直接使用包或重新设计来避免它。

  1. 直接执行,如this video所示。我不推荐这个,除非你真的知道你在做什么,并且有充分的理由这样做。它涉及直接观察您的第一个查询,并在发生更改时手动将更新推送到客户端。我认为David Weldon很好地总结了它in this answer
  2. 对数据进行反规范化,这将要求您在规范数据源更改时跟踪重复项。这将复杂性转移到代码的另一个区域,并且不容易实现。有一些设计模式,例如CQRS,允许您以相当强大和高效的方式实现这一点,但它们不容易掌握和实现。
  3. 使用诸如reywood:publish-composite之类的软件包,这会使手动选项的价格低于潜在的性能损失。
  4. 更改您的数据结构以便于发布。这取决于您的用例和其他要求。在您的情况下,在每个评论文档中都有articleId将使每篇文章的所有评论都发布得很简单。您可能希望为该字段添加索引以提高性能。
  5. 顺便说一下,"反应性加入"由于基于GrapnQL的新数据模型很快将通过Apollo传到Meteor,因此问题仍未得到解决。