Meteor,Cursor不与Collection保持同步

时间:2014-02-19 01:57:37

标签: meteor

我正在使用一些表单输入来创建一个新的Student,其代码如下:

var student_id = Students.insert({firstname: firstInput, lastname: lastInput, price: priceInput});
Meteor.users.update({_id: Meteor.userId()}, {$push: {'student_ids': student_id}});

我设置了以下订阅和出版物:

// On the client.
Meteor.subscribe('currentUser');

// On the server.
// I know this is ugly, but I need to do quite a bit of joining.
Meteor.publish('currentUser', function() {
    if (!this.userId) return;
    var userCursor = Meteor.users.find({_id: this.userId}, { fields: {firstname: true, lastname: true, student_id: true, student_ids: true, payment_ids: true, phones: true }});
    var user = userCursor.fetch()[0];
    if (user.student_ids || user.payment_ids) {
        var student_ids = user.student_ids || [];
        var studentCursor = Students.find({_id: {$in: student_ids}});

        var payment_ids = user.customer.payment_ids || [];
        var paymentCursor = Payments.find({_id: {$in: payment_ids}});

        var lesson_ids = [];
        var expense_ids = [];
        studentCursor.forEach(function(doc) {
            lesson_ids.concat(doc.lesson_ids);
            expense_ids.concat(doc.expense_ids);
        });
        var lessonCursor = Lessons.find({_id: {$in: lesson_ids}});
        var expenseCursor = Expenses.find({_id: {$in: expense_ids}});

        return [userCursor, studentCursor, lessonCursor, expenseCursor, paymentCursor];
    }
    else return userCursor;
});

问题是我的{{#each}}块之一正在列出所有这些学生,并且它工作正常,除了在页面刷新/重新启动等之前它不显示新学生。发布/订阅对没有被动反应。

我不确定如何优雅地解决这个问题。我绝对不希望在发布函数中混淆added和其他类似的回调。看来我的收藏品应该自己处理这种行为。

提前致谢!

更新

我将发布更改为使用publish-with-relations,一个反应式加入包,它现在看起来像这样:

Meteor.publish('currentUser', function() {
    var studentMappings = [{
        key: 'lesson_ids',
        collection: Lessons,
    },{
        key: 'expense_ids',
        collection: Expenses,
    }];

    return Meteor.publishWithRelations({
        handle: this,
        collection: Meteor.users,
        filter: this.userId,
        options: { fields: {firstname: true, lastname: true, student_id: true, student_ids: true, payment_ids: true, phones: true }},
        mappings: [{
            key: 'student_id',
            collection: Students,
            mappings: studentMappings
        },{
            key: 'student_ids',
            collection: Students,
            mappings: studentMappings
        },{
            key: 'payment_ids',
            collection: Payments,
        }]
    });
});

所有内容都已发布,但仍然没有被动!当页面重新加载时,所有内容都按预期进行,但在添加新学生后,该学生只会闪烁(我怀疑这是工作中的延迟补偿)。

当我在控制台中查询Meteor.user()时,student_ids数组是正确的:

student_ids: Array[1]
    0: "5dafpCD7XGcBnyjWd"
  length: 1

当我meteor mongo时:

meteor:PRIMARY> db.students.find()
{ "firstname" : "Sterling", "lastname" : "Archer", "price" : "22.50", "_id" : "5dafpCD7XGcBnyjWd" }

一切都是正确的,但在页面刷新之前,文档仍然不会显示。

是不是publish-with-relations应该解决这个问题?

1 个答案:

答案 0 :(得分:2)

发布功能不具有反应性。即使用户文档发生更改,发布也会重新运行并将学生文档发送给客户端。你需要的是一个反应性连接。请参阅this answer了解实用解决方案,this post了解更多启示。

更新

根据以下评论,此处提供了有关如何根据用户更改触发发布的建议。请注意,您实际上不必在发布函数中对student_ids执行任何操作 - 只是为了触发对该键的更改的订阅。

Tracker.autorun(function() {
  if (Meteor.user()) {
    Meteor.subscribe('students', Meteor.user().student_ids);
  }
});