Как использовать метеоритные зацепки
Я хочу отображать пользователей, которые в данный момент находятся в сети и имеют фокус на специальной странице. Где-то на этой странице мне нравится отображать список пользователей и их статус (включен / отключен фокус / нет фокусировки)
Я нашел этот пакет: https://atmospherejs.com/benjaminrh/event-hooks
Настройка понятна, это в документах. Но я не понимаю, как использовать крючки. Например:
Hooks.onLoseFocus = function ([server: userId]) { ... }
(в любом месте) - обеспечить обратный вызов для запуска, когда окно теряет фокус.
Таким образом, функция принимает идентификатор пользователя.
Имея в виду вышеупомянутый макет, у меня будет где-то дополнительный шаблон и каждый цикл вроде:
{{#each userstatus}}
{{>users_stats}
{{/each}}
Как бы я создал пользовательский статус, когда хук принимает индивидуальные идентификаторы пользователей?
1 ответ
Хорошо, вот полностью работающее решение, которое отслеживает пользователей, просматривающих в данный момент конкретный маршрут, и отображает этот список пользователей через помощника. Это работает в предположении, что вы используете iron:router
:
Сервер:
Hooks.onCloseSession = function() {
Meteor.call('clearUserFocus', function(error, result) {
if(error)
console.log(error);
});
}
Meteor.methods({
'setUserFocus': function(_routePath) {
Meteor.users.update({_id: Meteor.userId()}, {$set: {focus: _routePath}});
},
'clearUserFocus': function() {
var userId = Meteor.userId();
Meteor.users.update({_id: userId}, {$unset: {focus: ''}});
}
});
onCloseSession
кажется, только надежно работает на сервере, как и следовало ожидать.
Клиент:
Meteor.startup(function() {
// Start hooks, for user focus tracking
Hooks.init({
updateFocus: 500
});
});
Hooks.onGainFocus = function() {
// Router.current().route.getName(); // route name
var routePath = Iron.Location.get().pathname; // route path
Meteor.call('setUserFocus', routePath, function(error, result) {
if(error)
console.log(error);
});
}
Hooks.onLoseFocus = function() {
Meteor.call('clearUserFocus', function(error, result) {
if(error)
console.log(error);
});
}
Клиентский Глобальный Маршрутизатор:
Router.onBeforeAction(function() {
// Record user focus
var routePath = Iron.Location.get().pathname;
Meteor.call('setUserFocus', routePath, function(error, result) {
if(error)
console.log(error);
});
this.next();
});
Помощник шаблона клиента:
Template.yourTemplateName.helpers({
'focusedUsers': function() {
var routePath = Iron.Location.get().pathname;
return Meteor.users.find({focus: routePath});
}
});
Шаблон клиента:
<ul>
{{#each focusedUsers}}
<li>{{_id}}</li>
{{/each}}
</ul>
Это работает очень хорошо для меня, мне нужно тщательно проверить это, хотя я обнаружил, по крайней мере, одно предупреждение. Когда работает несколько окон, кажется, что его можно спутать с фокусом.
Также обратите внимание, что для доступа к users
публикация (как бы она ни называлась), чтобы помощник имел доступ к коллекции и мог получить focus
, Что вы можете сделать так:
// Global router settings
Router.configure({
layoutTemplate: 'defaultLayout',
loadingTemplate: 'loading',
waitOn: function() {
return Meteor.subscribe('users');
}
});
По запросу: обратите внимание, что это включает необязательный пример макета по умолчанию и шаблонов загрузки. Загружаемый шаблон заменяет содержимое layoutTemplate {{> yield}} до тех пор, пока не будут готовы подписки waitOn (как глобальные, так и специфичные для маршрута).
Я также получаю сообщение об ошибке консоли браузера, которое, насколько я могу судить, ничем не мешает, но мне не нравится, когда оно появляется: "Ошибка вызова метода" eventsOnHooksInit': Метод не найден [404]'