繁体   English   中英

在3个馆藏之间以复杂的方式创建多对多关系

[英]Creating a many to many relationship in a complex manner between 3 collections

我有3个收藏集, meteor.user()CategoriesPosts

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

最终目的是使用户拥有一个“个人”流,其中显示他们正在关注的类别中的帖子。

Posts collection每个Posts collection都包含一个以其为特色的Categories数组。

在此处输入图片说明

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

在此处输入图片说明

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

以下是帖子集合中帖子的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与Post中Post的ID,以便可以从Posts集合中访问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答案后的进一步编辑

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

在此处输入图片说明

Category collectionpost数组不完整,它是原始Posts Collection的副本

我需要做的是使用上图所示的post.ID 即类别集合中的帖子数组,以与原始Posts集合中的Posts id建立多对多关系 ,因此, post.title具有post.title我还需要具有title.rendered ,如下所示。

帖子集合。

在此处输入图片说明

如果您发现该ID (不是顶级的ID,这是该类别的ID), post.ID类别集合中的后阵列中是相同id在后的Posts集合。 这就是全部的症结所在,可以帮助我建立一种关系,这样,我需要在原始的Posts集合中显示title.rendered ,而不是显示Categories集合中的post数组titlepost.title

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

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);
    });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM