我对流星很新,我遇到了订阅回调的奇怪问题。我有一个包含课程和评论的数据库。我在评论中使用发布/订阅模型来返回仅与所选类相关的评论,并且我希望每次单击新类时都要更改。我想打印所有评论并编制一些关于评论的指标(平均质量,难度等级)。使用以下代码,使用订阅更新发送给客户端的评论,打印的评论(从帮助程序中获取)正确返回,但指标(在onReady回调到辅助程序时抓取)是不准确的。运行onReady函数时,本地评论集合的当前结果包含单击的类和先前单击的类的并集,即使评论本身打印正确。
我也试过使用autoTracker,但我得到了相同的结果。有没有办法在更新之前清除以前的订阅结果?
发布:
Meteor.publish('reviews', function validReviews(courseId, visiblity) {
console.log(courseId);
console.log(visiblity);
var ret = null
//show valid reviews for this course
if (courseId != undefined && courseId != "" && visiblity == 1) {
console.log("checked reviews for a class");
ret = Reviews.find({class : courseId, visible : 1}, {limit: 700});
} else if (courseId != undefined && courseId != "" && visiblity == 0) { //invalidated reviews for a class
console.log("unchecked reviews for a class");
ret = Reviews.find({class : courseId, visible : 0},
{limit: 700});
} else if (visiblity == 0) { //all invalidated reviews
console.log("all unchecked reviews");
ret = Reviews.find({visible : 0}, {limit: 700});
} else { //no reviews
console.log("no reviews");
//will always be empty because visible is 0 or 1. allows meteor to still send the ready
//flag when a new publication is sent
ret = Reviews.find({visible : 10});
}
//console.log(ret.fetch())
return ret
});

订阅:
this.helpers({
reviews() {
return Reviews.find({});
}
});

并使用帮助程序在构造函数中订阅调用:
constructor($scope) {
$scope.viewModel(this);
//when a new class is selected, update the reviews that are returned by the database and update the gauges
this.subscribe('reviews', () => [(this.getReactively('selectedClass'))._id, 1], {
//callback function, should only run once the reveiws collection updates, BUT ISNT
//seems to be combining the previously clicked class's reviews into the collection
onReady: function() {
console.log("class is: ", this.selectedClass);
if (this.isClassSelected == true) { //will later need to check that the side window is open
//create initial variables
var countGrade = 0;
var countDiff = 0;
var countQual = 0;
var count = 0;
//table to translate grades from numerical value
var gradeTranslation = ["C-", "C", "C+", "B-", "B", "B-", "A-", "A", "A+"];
//get all current reviews, which will now have only this class's reviews because of the subscribe.
var allReviews = Reviews.find({});
console.log(allReviews.fetch());
console.log("len is " + allReviews.fetch().length)
if (allReviews.fetch().length != 0) {
console.log("exist")
allReviews.forEach(function(review) {
count++;
countGrade = countGrade + Number(review["grade"]);
countDiff = countDiff + review["difficulty"];
countQual = countQual + review["quality"];
});
this.qual = (countQual/count).toFixed(1);
this.diff = (countDiff/count).toFixed(1);
this.grade = gradeTranslation[Math.floor(countGrade/count) - 1];
} else {
console.log("first else");
this.qual = 0;
this.diff = 0;
this.grade = "-";
}
} else {
console.log("second else");
this.qual = 0;
this.diff = 0;
this.grade = "-";
}
}
})

答案 0 :(得分:0)
当使用pub-sub时,客户端上的minimongo数据库将包含订阅的并集,除非它们被明确清除。因此,您希望在客户端重复发布中的查询,以便以相同的方式进行筛选和排序。 Minimongo在客户端上速度非常快,通常你的数据少得多,所以不要担心性能。
在你的constructor
中:
var allReviews = Reviews.find({});
改为使用:
var allReviews = Reviews.find(
{
class : (this.getReactively('selectedClass'))._id,
visible : 1
},
{limit: 700}
);
另一个提示:javascript是关于 truthy 和 falsy 值的quite clever。
if (courseId != undefined && courseId != "" && visibility == 1)
可以简化为:
if (courseId && visibility)
假设您使用visibility == 1
表示true
而visibility == 0
表示false