0

我有 3 个集合meteor.user()CategoriesPosts

用户可以通过将类别的 id 保存在数组中来选择关注任何类别的帖子meteor.user()

这样做的最终目标是用户拥有一个个人信息流,其中显示他们关注的类别中的帖子。

里面的每个帖子Posts collection都有一个包含它的类别的数组。

在此处输入图像描述

每个类别都有一个帖子数组,数组中的每个帖子都有一个帖子字段ID

在此处输入图像描述

whereid: 67是类别的 id,是类别posts.ID: 74中的帖子的 id。

下面是 Posts 集合中帖子的 ID,与类别集合中的 posts.ID 匹配

在此处输入图像描述

用户保存一个类别 id,因此它在meteor.user() 中显示为类别数组

在此处输入图像描述

当我这样做时

Template.userTimeline.helpers({
  category: function() {
    var posts = Category.find({
      id: {
        $in: Meteor.user().category
      }
    });
    return posts
    console.log(posts);
  }
});

我可以做这个

 {{#each category}}
  <ul class="article-timeline">
    {{#each posts}} {{ID}} {{/each}}
  </ul>
{{/each}}

但这让我可以访问类别集合中的 posts.ID 并显示它。

问题

我怎样才能走得更远,将我用上面的代码得到的posts.ID匹配到一个帖子的id,Post这样我就可以访问Posts集合中的帖子。我可以做这样的事情吗?

Template.userTimeline.helpers({
  category: function() {
    var postsInCategory = Category.find({
      id: {
        $in: Meteor.user().category
      }
    });

    var postMatch = Post.find({
      ID: {
        $in: postsInCategory
      }
    });
    return postMatch
    console.log(postMatch);
  }
});

ZIM 回答后的进一步编辑

因此,您给我的解决方案是从我的收藏中包含post.title的 post 对象中获取,如下所示。Categories

在此处输入图像描述

中的这个post数组Category collection是不完整的,它是一个原始的副本Posts Collection

我需要做的是使用post.ID如上图所示。即类别集合中的帖子数组,以创建与原始集合中的帖子的多对多关系,而不是让我需要如下所示。idPostspost.titletitle.rendered

帖子集合。

在此处输入图像描述

如果您看到ID(不是顶部 id,它是类别的 id),则Categories集合中post.ID的帖子数组中的帖子与集合中的帖子相同。这是这一切的关键,帮助我创建一个关系,这样,我需要在原始集合中显示,而不是显示或来自集合的帖子数组。idPoststitlepost.titleCategoriestitle.renderedPosts

4

1 回答 1

1

听起来您无法控制数据格式,因此您必须使用嵌套循环来处理您拥有的格式。我认为以下应该有效。

Template.userTimeline.helpers({
  categories: function() {
    return Category.find({
      id: {
        $in: Meteor.user().category
      }
    });
  }
});

请注意,我更改了您的助手的名称。

{{#each category in categories}}
  {{category.description}}
  {{#each post in category.posts}}
    {{post.title}}
  {{/each}}
{{/each}}

cf http://blazejs.org/guide/spacebars.html#Each-in

编辑:

理想情况下,您可以使用https://atmospherejs.com/reywood/publish-composite之类的包进行服务器端连接

但由于您无法控制它,您可以进行客户端连接。您可以在模板的 onCreated() 中执行此操作(警告:这是未经测试的!)

this.subscribe('posts', function() {
    let cursor = Categories.find({id: {$in: Meteor.user().category}});

    cursor.observe({
        added: function(newDocument) {
            let category = newDocument;

            // for this category, get all the associated post ids
            let postIds = _.map(category.posts, function(p)) {
                return p.ID;
            };

            // get the posts. we can fetch these because we waited for the publish of the posts collection.
            let actualPosts = Posts.find({id: {$in: postIds}}).fetch();

            // attach the actual posts to the category
            category.actualPosts = actualPosts;
        },
        changed: function(newDocument, oldDocument)  {
            // if wanting to track changes to the categories, similar to added block
        }
    });
});

然后通过对模板的简单更改,您可以获取这些实际帖子:

{{#each category in categories}}
  {{category.description}}
  {{#each post in category.actualPosts}}
    {{post.title}}
  {{/each}}
{{/each}}

进行客户端连接有点棘手,因为如上所述,您缺少对用户跟踪类别的反应性,以及现有类别中的帖子。所以你可以进一步把所有这些都放在自动运行中。这将跟踪对 Meteor.user().category 的更改,但不确定是否会跟踪类别中的帖子更改。但这应该会让你走得很远。

编辑2:

哦,是的,如果你这样做,当模板消失时,监听器将保持活动状态,除非你在它上面调用 stop()。所以...

Template.userTimeline.onDestroyed(function() {
    let handle = this.observeHandle.get();

    if (handle) {
        handle.stop();
    }
});

Template.userTimeline.onCreated(function() {
    let self = this;
    self.observeHandle = new ReactiveVar();

    self.subscribe('posts', function() {
        let cursor = Categories.find({id: {$in: Meteor.user().category}});

        let handle = cursor.observe({
            added: function(newDocument) {
                let category = newDocument;

                // for this category, get all the associated post ids
                let postIds = _.map(category.posts, function(p)) {
                    return p.ID;
                };

                // get the posts
                let actualPosts = Posts.find({id: {$in: postIds}}).fetch();

                // attach the actual posts to the category
                category.actualPosts = actualPosts;
            },
            changed: function(newDocument, oldDocument)  {
                // if wanting to track changes, similar to added block
            }
        });

        self.observeHandle.set(handle);
    });
});
于 2017-06-02T17:48:48.240 回答