У меня есть коллекция предметов, которые мои пользователи могут пометить как "прочитанные".
Чтобы пометить коллекцию как «прочитанную», добавляется поддокумент:
"readby": [
{
"action": "read",
"owner": "w5XzMrCCJJfDxCn6d"
}
]
Затем я использую следующий помощник, чтобы установить массив и выдвинуть все «прочитанные» записи, которые соответствуют текущему владельцу. Если длина массива больше 0, помощник возвращает «true», и мы знаем, что вошедший в систему пользователь прочитал этот элемент:
itemHasBeenRead() {
var subscribers = [];
var readItems = this.readby;
if(!readItems) {
return false;
}
var readiness = readItems.forEach(function(currentSubscriber) {
// loop over current users expenses
var newSubscriber = { owner: currentSubscriber.owner };
if (currentSubscriber.owner == Meteor.userid()) {
subscribers.push(newSubscriber);
}
});
return subscribers && subscribers.length > 0
}
Все это прекрасно работает, НО, насколько я понимаю, в Meteor поддокументы не реагируют, поэтому код не реагирует на изменения. Обновите страницу, и она отлично работает.
Есть ли способ сделать это реактивно, а не только при загрузке страницы?
-
Правка по запросу:
-
Код шаблона:
{{#each playlists}}
<h2 class="playlistheader">{{playlistName}}<span class="badge badge-playlist badge-playlist-first badge-primary"><i class="fas fa-users playlist-fa"></i>{{numberOfSubscribers}} enrolled</span>{{#unless isPlaylistOwner}}{{#unless userIsSubscribed}}<span class="badge badge-playlist badge-success subscribe-unsubscribed" data-id="{{this._id}}"><i class="far fa-heart playlist-fa"></i>Enrol</span>{{/unless}}{{#if userIsSubscribed}}<span class="badge badge-playlist badge-success subscribe-subscribed" data-id="{{this._id}}"><i class="fas fa-heart playlist-fa"></i>Enrolled</span>{{/if}}{{/unless}}
<span class="badge badge-playlist badge-completion" data-id="{{this._id}}"><i class="fas fa-check-circle" style="margin-right:3px;"></i>0/6 items marked complete</span>
{{#if isPlaylistOwner}}<span class="badge badge-playlist badge-danger badge-delete" data-id={{this._id}}><i class="fas fa-ban playlist-fa"></i>Delete</span>{{/if}}</h2>
<span class="playlist-subheader">{{playlistPrivacyType}} collection by {{playlistOwnerName}}</span>
<div class="row" style="display:inherit; margin-left:0px; margin-bottom:20px;margin-top:8px;">
<div class="scrolling-wrapper-playlist">
{{#if isPlaylistOwner}}
<div class="playlist-product playlist-product-add" data-playlistid="{{playlistid}}">
<div class="clampcontainer">
<div class="add-playlist-plus" data-playlistid="{{playlistid}}">+</div>
</div>
</div>
{{/if}}
{{#each playlistItems this._id}}
<div class="playlist-product" data-id={{this._id}}>
{{#if isPlaylistItemOwner}}
<div class="playlist-product-delete">
<i class="fas fa-times-circle product-delete"></i>
</div>{{/if}}
<div class="playlist-product-overlay" id="overlay-{{this._id}}" style="opacity:0;">
<div class="playlist-product-overlay-description">
"{{itemDescription}}"</div>
<div class="playlist-product-overlay-icons">
{{#unless itemHasBeenRead}}
<i class="far fa-check-circle playlist-circle"></i>
{{/unless}}
{{#if itemHasBeenRead}}
<i class="fas fa-check-circle playlist-circle"></i>
{{/if}}
{{#if hasPrice}}
<i class="fas fa-shopping-cart playlist-cart"></i>
{{/if}}
<i class="fas fa-external-link-alt playlist-external"></i>
</div>
</div>
<div style="width:90px; float:left; margin-right:10px;"><img src="{{itemImage}}" width="90"></div>
<div class="clampcontainer">
<div class="itemTitle linkColor">{{itemTitle}}</div>
<p class="itemDescription">{{itemDescription}}...</p>
<div class="fadeout"></div>
</div>
</div>
{{/each}}
</div>
</div>
{{/each}}
Код публикации:
Meteor.publish('UserPlaylists', function() {
var loggedinuser = Meteor.user();
// Reveal ALL expenses if it's an admin who's logged in
return Playlists.find({
owner: loggedinuser._id
});
});
// Publish public playlists, as long as they're both public and from the same company
Meteor.publish('PublicPlaylists', function() {
var loggedinuser = Meteor.user();
var companyid = loggedinuser.userofcompanyid;
// Reveal ALL expenses if it's an admin who's logged in
return Playlists.find({
companyid: companyid,
published: true
});
});
// Publishes absolutely all expenses for superadmins
Meteor.publish('Playlists', function() {
var loggedinuser = Meteor.user();
if (loggedinuser.issuperadmin) {
return Playlists.find({});
}
});
Подписка на публикации в шаблоне js:
Template.Playlists.onCreated(function playlistsOnCreated() {
var self = this;
self.autorun(function() {
self.subscribe('UserPlaylists');
self.subscribe('PublicPlaylists');
self.subscribe('UserPlaylistItems');
self.subscribe('PublicPlaylistItems');
});
});
Помощник плейлистов:
playlists() {
return Playlists.find({}, {
sort: {
timestamp: -1
}
});
},
Помощник PlaylistItems:
playlistItems(playlistid) {
return PlaylistItems.find({
playlistid: playlistid
}, {
sort: {
timestamp: -1
}
});
},