Проблема вложения Meteor Publish-Composite

Проблема. У меня есть несколько групп, в каждой из которых есть участники, принадлежащие к разным группам. Каждый участник имеет титул (роль) в каждой группе. Я пытаюсь перечислить все группы и отобразить каждого члена в группе и их название. Я использую reywood:publish-composite, и все работает, за исключением того, что я не могу отобразить заголовок каждого члена. Я думаю, что проблема в файле Template.groupMembers.helpers.

 title: function() {
        console.log(this.roleId); // this shows up in the console for each member
        return Titles.findOne({titleId: this.roleId}); // but this doesn’t work 
      },

Подборки:

groups {
    "_id" : "xFSzAHBEps2dSKcWM",
    "name" : "Generic Group",
    "logo" : "generic-logo-hi.png"
}


members {
    "_id" : "vyDtiaKKukZYQdFvs",
    "groupId" : "xFSzAHBEps2dSKcWM",
    "memberId" : "hRx8GBTyB5X8iQQ52",
    "roleId" : "1"
}


Meteor.users {
    "_id" : "hRx8GBTyB5X8iQQ52",
    "profile" : {
        "name" : "Bob Lorros"
    },
 }


titles {
    "_id" : "bYsKpsyYtyKR8NYpm",
    "titleId" : 1,
    "title" : "Staff (non-voting)"
}

сервер/публикации/publications.js

Meteor.publishComposite('groupMembers', {
  find: function() {
      return Groups.find({}, {
        sort: {name: 1}
      });
    },
    children: [
        {
            find: function() {
                return Titles.find();
            },
            find: function(group) {
              return Members.find({groupId: group._id});
            },
            children: [
              {
                find: function(member) {
                    return Meteor.users.find({_id: member.memberId});
                }
              },
            ]
        },
    ]
});

клиент/шаблоны/тест/test.js

Template.groupMembers.helpers({
  groupMembers: function() {
    return Groups.find({}, {
      sort: {name: 1}
    });
  },
  members: function() {
    return Members.find({groupId: this._id});
  },
  title: function() {
    console.log(this.roleId); // this shows up in the console for each member
    return Titles.findOne({titleId: this.roleId}); // but this doesn’t work 
  },
  memberName: function() {
    return Meteor.users.findOne(this.memberId);
  },
});

клиент/шаблоны/тест/test.html

<template name="groupMembers">
  <h4>Group - Members</h4>
  {{#each groupMembers}}
    <b>{{name}}</b><br>
    {{#each members}}
       &nbsp;{{memberName.profile.name}}
        - title = {{title.title}}
        <br>
    {{/each}}
    <br>
  {{/each}}
</template>

Вывод: это вывод


person Bob Lorriman    schedule 02.02.2016    source источник


Ответы (3)


Глядя на это с совершенно другой точки зрения, я действительно думаю, что вы могли бы использовать alanning:roles для достижения именно того, что вы ищете. Вы можете использовать роль в качестве «названия» в этом случае и «группу», чтобы заменить свои группы. Вот документация:

https://github.com/alanning/meteor-roles

person Stephen Woods    schedule 03.02.2016
comment
Спасибо @StephenWoods - похоже, это может сработать. - person Bob Lorriman; 05.02.2016

Не уверен, но я думаю, что ваш второй find может быть важнее вашего первого. Вместо:

find: function() {
  return Titles.find();
},
find: function(group) {
  return Members.find({groupId: group._id});
},

Попробуйте вернуть массив курсоров.

find: function() {
  return [
    Titles.find(),
    Members.find({groupId: group._id})
  ];
},

Однако я не понимаю, почему Titles является дочерним элементом GroupMembers, когда запрос на заголовки - это все заголовки. Вы хотели задать вопрос там?

person Michel Floyd    schedule 03.02.2016
comment
Спасибо @MichaelFloyd, но подход с массивом вызвал ошибку объекта. - person Bob Lorriman; 04.02.2016

Я думаю, что ваш publishComposite вызывает проблему, каждый объект в дочернем массиве должен иметь только один find и ноль или более children. Также второй параметр в вашей публикации должен быть функцией, а не объектом JSON. Попробуй это,

 Meteor.publishComposite('groupMembers', function () {
     return {
        find: function() {
            return Groups.find({}, {
               sort: {name: 1}
            });
        },
        children: [{
           find: function() {
              return Titles.find();
           }
        },
        {
           find: function(group) {
              return Members.find({groupId: group._id});
           },
           children: [{
              find: function(member) {
                 return Meteor.users.find({_id: member.memberId});
              }
           }]
        }]
     };
 });

Вы также можете повысить производительность, переместив Titles.find на корневой уровень.

    Meteor.publishComposite('groupMembers', function () {
     return [{
        find: function() {
           return Titles.find();
        }
     }, {
        find: function() {
            return Groups.find({}, {
               sort: {name: 1}
            });
        },
        children: [{
           find: function(group) {
              return Members.find({groupId: group._id});
           },
           children: [{
              find: function(member) {
                 return Meteor.users.find({_id: member.memberId});
              }
           }]
        }]
     }];
 });
person Kishor    schedule 03.02.2016