Шаблон Метеор перезагрузить бесконечность


У меня есть проблема при работе с Meteor.

У меня есть страница" вопрос", на которой я хочу увеличить количество просмотров всякий раз, когда она отображается.

Поэтому в моей шаблонной функции я пишу

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
        }
     });
   }
});

Теперь возникает проблема, когда я визуализирую представление вопроса и обновляю элемент вопроса, представление обновляется снова, потому что это отражающая страница. А потом наступает бесконечность петли.

У кого-нибудь есть предложения?

4 6

4 ответа:

Как правило, в подобных ситуациях в модели что-то нарушается. В данном случае, я считаю, что это идея "графического представления". Есть много способов сделать это правильно. Приращение его на рендере не является таковым, поскольку вы выполняете работу модели в коде пользовательского интерфейса (нарушенном концептуально и в реализации).

Во-первых, сохраните вопросы, которые пользователь посетил где-то. Почему не свойство {questionsVisited:[]} для пользователя?

Вместо этого используйте вызов метода Meteor.call(...) для регистрации представления:

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;
});

Так как же об увеличении представления об изменениях пользовательского интерфейса? Ну, давайте не будем делать этого специально. Давайте увеличим количество просмотров только , когда вопрос изменится.

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();
  });
});

И избавьтесь от всех этих вспомогательных вопросов...

Это даже лучше, чем то, что вы изначально хотели. Теперь просмотры не учитываются дважды для одного и того же пользователя. Если это желаемое поведение, удалите логику questionsVisited.

только измените переменную сеанса 'question_id', Когда вы фактически изменяете логическую вопрос, с которым работает пользователь.

Я решил эту задачу с помощью meteor-collection-hooks

Сначала установите его

>_ meteor add matb33:collection-hooks

Тогда в вашей модели

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

И бабах Вот оно

Вместо того, чтобы вставлять помощника, я бы вложил эту логику в визуализируемое событие, т. е.

Template.questionview.rendered ...

СмотритеThe Meteor docs .

Если вы используете publish и subscribe (вы определенно должны в любом случае), вы можете сделать это на вашем методе публикации, как

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

Или на обратном вызове подписки

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

Таким образом, вы увеличиваете счетчик только один раз, когда пользователи открывают браузер.