Meteor + MongoDB: 如何获取嵌套数据?

Meteor + MongoDB: How to get nested data?

我是 Meteor 的新手,正在尝试解决我遇到的这个问题。

我正在尝试根据传递的路线从课程 collection 中加载数据。例如,如果 /courses/level1/lesson1/1a 已通过,则显示数据

不幸的是,这不起作用。

我走在正确的道路上还是有更好的方法?

Collection

{
  "_id": "YSgr3fvjpEBn7ncRa",
  "courseId": "level1",
  "lesson": [
    {
      "lessonId": "lesson1",
      "freeLesson": true,
      "title": "Lesson 1",
      "eachLesson": [
        {
          "eachLessonId": "1a",
          "title": "This is (masculine)",
          "video": "839843"
        },
        {
          "eachLessonId": "1b",
          "title": "That is (masculine)",
          "video": "839843"
        },
        {
          "eachLessonId": "1c",
          "title": "This is (feminine)",
          "video": "839843"
        },
        {
          "eachLessonId": "1d",
          "title": "That is (feminine)",
          "video": "839843"
        },
        {
          "eachLessonId": "1e",
          "title": "Getting to know you",
          "video": "839843"
        }
      ]
    }
  ]
}

路线

 Router.route("courses/:courseId/:lessonId/:eachLessonId", {
  path:"/courses/:courseId/:lessonId/:eachLessonId",
  layoutTemplate: "layoutLessons",
  template:"lessons",
  onBeforeAction:function(){
    var currentUser = Meteor.userId();
    if (currentUser) {
      Session.set('courseId', this.params.courseId);
      Session.set('lessonId', this.params.lessonId);
      Session.set('eachLessonId', this.params.eachLessonId);
      this.next();
     } else {
       Router.go('/')
     }
  },
});

模板助手

Template.lessons.onCreated(function(){
  Meteor.subscribe('listLessons');
});


Template.lessons.helpers({
  currentLesson: function() {
    var currentLesson = Session.get('eachLessonId');
    return Lessons.find({"lesson.eachLesson.eachLessonId" : currentLesson});
  },
});

HTML

{{#each currentLesson}}
  {{title}}
  {{video}}
{{/each}}

您可以使用 Iron Router's waitOn and data 选项,而不是将 courseIdlessonIdeachLessonId 存储为 Session 值。

例如,您可以按如下方式重写路线:

Router.route('/courses/:courseId/:lessonId/:eachLessonId', {
  name: 'lessons',
  layoutTemplate: 'layoutLessons',
  template: 'lessons',
  onBeforeAction: function() {
    let currentUser = Meteor.user();
    if (currentUser) this.next();
    else Router.go('/');
  },
  data: function() {
    var doc = Lessons.findOne({
      "courseId": this.params.courseId,
      "lesson.lessonId": this.params.lessonId,
      "lesson.eachLesson.eachLessonId": this.params.eachLessonId
    });
    if (doc) {
      var lesson = {};
      var lessonId = this.params.eachLessonId;
      _.each(doc.lesson, function(i) {
        lesson = _.find(i.eachLesson, function(j) {
          return j.eachLessonId == lessonId;
        });
      });
      return lesson;
    }
    return {};
  },
  waitOn: function() {
    return [
      Meteor.subscribe('lesson', this.params.courseId, this.params.lessonId, this.params.eachLessonId)
    ];
  }
});

这应该将数据上下文设置为请求的 eachLesson 对象。但是,您可以考虑将数据上下文设置为 Lessons 集合中的文档,然后只选择某些 eachLesson 对象。此外,您应该创建一个发布功能,其中 returns 只是请求的 Lessons 文档而不是所有文档,就像您现在在 listLessons 出版物中所做的那样。您可以将所有 ID 作为参数传递给相应的发布函数。