【问题标题】:Meteor subscribe callback running when subscription contains previous subscribe result订阅包含先前订阅结果时运行的 Meteor 订阅回调
【发布时间】:2017-05-08 02:50:09
【问题描述】:

我对流星还很陌生,我遇到了一个关于订阅回调的奇怪问题。我有一个包含课程和评论的数据库。我在评论上使用发布/订阅模型来返回仅与所选课程相关的评论,并且我希望每次单击新课程时都会更改此内容。我想打印所有评论并编制一些关于评论的指标(平均质量、难度等级)。使用以下代码,使用更新发送给客户端的评论的订阅,打印的评论(从帮助程序获取)正确返回,但指标(在对帮助程序的 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 = "-";
        } 
      } 
    })

【问题讨论】:

    标签: javascript angular meteor callback


    【解决方案1】:

    当使用 pub-sub 时,客户端上的 minimongo 数据库将包含订阅的联合,除非它们被明确清除。出于这个原因,您希望在客户端重复发布中的查询,以便以相同的方式进行过滤和排序。 Minimongo 在客户端上的速度非常快,通常那里的数据要少得多,所以不用担心性能。

    在您的constructor 中,您有:

    var allReviews = Reviews.find({});
    

    改为使用:

    var allReviews = Reviews.find(
      {
        class : (this.getReactively('selectedClass'))._id,
        visible : 1
      },
      {limit: 700}
    );
    

    另一个提示:javascript 是关于 truthyfalsy 值的quite clever

    if (courseId != undefined && courseId != "" && visibility == 1)
    

    可以简化为:

    if (courseId && visibility)
    

    假设您使用visibility == 1 表示truevisibility == 0 表示false

    【讨论】:

    • 谢谢!完美解决了问题!
    猜你喜欢
    • 2015-04-21
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 2019-04-12
    相关资源
    最近更新 更多