Meteor template reload infinity

孤者浪人 提交于 2020-01-12 20:17:30

问题


I have a problem when running with Meteor.

I have a "question" page which I want to increase the count view whenever it is rendered.

So in my template function I write

Template.questionview.helpers({
    question : function() {
      if(Session.equals('main_template_name', 'question')) {
        console.log(Session.get('question_id'));
        Questions.update({
          _id: Session.get('question_id')
        }, {
           $inc: {
           views: 1
        }
     });
   }
});

Now here comes the problem, when I render the question view and update the question item, the view is refreshed again because it is a reflective page. And then it comes infinity loop.

Anyone has suggestions?


回答1:


Typically, in situations like this, there is something broken about the model. In this case, I believe it's the "count view" idea. There are lots of ways to do this correctly. Incrementing it on render is not, since you're doing model work in UI code (broken conceptually and in implementation).

First, store the questions the user has visited somewhere. Why not a {questionsVisited:[]} property on the user?

Use a Meteor.call(...) method call to register a view instead:

Meteor.methods({
  viewQuestion: function(questionId) {
    // check if the user hasn't visited this question already
    var user = Meteor.users.findOne({_id:this.userId,questionsVisited:{$ne:questionId}});

    if (!user)
         return false;

    // otherwise, increment the question view count and add the question to the user's visited page
    Meteor.users.update({_id:this.userId},{$addToSet:{questionsVisited:questionId}});
    Questions.update({_id:questionId},{$inc:{views:1}});
    return true;
});

So how about incrementing the view on UI changes? Well, let's not do that specifically. Let's increment the view count only when the question changes.

Meteor.autorun(function () {
  var questionId = Session.get("question_id");
  Meteor.call('viewQuestion',questionId,function(e,r) {
    if (r)
      console.log("Question " + questionId + " logged an increment.");
    else 
      console.log("Question " + questionId + " has already been visited by user " + Meteor.userId();
  });
});

And get rid of all this question helper stuff...

This is even better than what you originally wanted. Now views aren't counted twice for the same user. If that is the desired behavior, remove the questionsVisited logic.

Only change the 'question_id' session variable when you actually change the logical question the user is working with.




回答2:


I solved this problem by using meteor-collection-hooks

First install it

>_ meteor add matb33:collection-hooks

Then in your model

Questions.after.findOne(function (userId, selector, options, doc){
    Questions.update({_id: doc._id},{$inc:{views:1}});
});

And KABOOM Thats it




回答3:


Rather than put in a helper, I would put this logic into the rendered event, ie.

Template.questionview.rendered ...

See the Meteor docs.




回答4:


If you are using publish and subscribe ( you definitely should anyway) you can do it on your publish method like

Meteor.publish('posts', function(id) {
  Posts.update({_id:id},{$inc:{view:1}});
  return Posts.find({_id: id});
});

or on your subscribe callback

 Meteor.subscribe("posts" , id {
    onReady: function() { Meteor.call("incrementView", id);}});

this way you only increment the count once each time users open the browser.



来源:https://stackoverflow.com/questions/13776820/meteor-template-reload-infinity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!