Шаблон Метеор перезагрузить бесконечность
У меня есть проблема при работе с 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 ответа:
Как правило, в подобных ситуациях в модели что-то нарушается. В данном случае, я считаю, что это идея "графического представления". Есть много способов сделать это правильно. Приращение его на рендере не является таковым, поскольку вы выполняете работу модели в коде пользовательского интерфейса (нарушенном концептуально и в реализации).
Во-первых, сохраните вопросы, которые пользователь посетил где-то. Почему не свойство
{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);}});
Таким образом, вы увеличиваете счетчик только один раз, когда пользователи открывают браузер.