Я не уверен, насколько это продвинет вас к решению ваших реальных проблем, но я начну с нескольких странностей в вашем коде и вопросов, которые вы задаете.
1) Вы спрашиваете о коллекции Phrases, но функция публикации никогда ничего не публикует в этой коллекции, поскольку все вызовы added
отправляются в коллекцию minimongo с именем «posts».
2) Вы спрашиваете о коллекции «Репосты», но ни один из кодов не использует это имя, поэтому неясно, о чем вы говорите. Однако каждый элемент, добавленный в коллекцию «Сообщения», создаст нового наблюдателя в коллекции «Общие ресурсы», поскольку он вызывает checkSharedId()
. Каждый наблюдатель будет пытаться добавлять и изменять документы в коллекции «сообщений» клиента.
3) Что касается пункта 2, mySharedHandle.stop()
остановит только последнего наблюдателя, созданного checkSharedId()
, потому что дескриптор перезаписывается каждый раз, когда запускается checkSharedId()
.
4) Если ваш наблюдатель «Shares» находит документ с IN_postId, он пытается отправить документ с этим _id в коллекцию «posts» minimongo. IN_postId передается из вашей находки в коллекции «Сообщения», а его наблюдатель также пытается отправить другой документ в коллекцию «сообщений» клиента. Какой документ вы хотите на клиенте с этим _id? Некоторые из ошибок, которые вы видите, могут быть вызваны попытками Meteor игнорировать повторяющиеся добавленные запросы< /а>.
Исходя из всего этого, я думаю, вам лучше разбить это на две функции публикации, одну для «Постов» и одну для «Поделиться», чтобы воспользоваться преимуществами курсоров публикации поведения метеоров по умолчанию. При необходимости любое соединение может быть выполнено на клиенте. Например:
//on server
Meteor.publish('posts', function(){
return Posts.find();
});
Meteor.publish('shares', function(){
return Shares.find( {userId: this.userId }, {fields: {postId: 1}} );
});
//on client - uses _.pluck from underscore package
Meteor.subscribe( 'posts' );
Meteor.subscribe( 'shares');
Template.post.isSharedByMe = function(){ //create the field isSharedByMe for a template to use
var share = Shares.findOne( {postId: this._id} );
return share && true;
};
Альтернативный метод присоединения к публикации с помощьюObservChanges. Непроверенный код, и мне не ясно, имеет ли он большое преимущество перед более простым методом, описанным выше. Поэтому, пока вышеперечисленное не сломается или не станет узким местом в производительности, я буду делать это, как указано выше.
Meteor.publish("posts", function(){
var self = this;
var sharesHandle;
var publishedPosts = [];
var initialising = true; //avoid starting and stopping Shares observer during initial publish
//observer to watch published posts for changes in the Shares userId field
var startSharesObserver = function(){
var handle = Shares.find( {postId: {$in: publishedPosts}, userId === self.userId }).observeChanges({
//other observer should have correctly set the initial value of isSharedByMe just before this observer starts.
//removing this will send changes to all posts found every time a new posts is added or removed in the Posts collection
//underscore in the name means this is undocumented and likely to break or be removed at some point
_suppress_initial: true,
//other observer manages which posts are on client so this observer is only managing changes in the isSharedByMe field
added: function( id ){
self.changed( "posts", id, {isSharedByMe: true} );
},
removed: function( id ){
self.changed( "posts", id, {isSharedByMe: false} );
}
});
return handle;
};
//observer to send initial data and always initiate new published post with the correct isSharedByMe field.
//observer also maintains publishedPosts array so Shares observer is always watching the correct set of posts.
//Shares observer starts and stops each time the publishedPosts array changes
var postsHandle = Posts.find({}).observeChanges({
added: function(id, doc){
if ( sharesHandle )
sharesHandle.stop();
var shared = Shares.findOne( {postId: id});
doc.isSharedByMe = shared && shared.userId === self.userId;
self.added( "posts", id, doc);
publishedPosts.push( id );
if (! initialising)
sharesHandle = startSharesObserver();
},
removed: function(id){
if ( sharesHandle )
sharesHandle.stop();
publishedPosts.splice( publishedPosts.indexOf( id ), 1);
self.removed( "posts", id );
if (! initialising)
sharesHandle = startSharesObserver();
},
changed: function(id, doc){
self.changed( "posts", id, doc);
}
});
if ( initialising )
sharesHandle = startSharesObserver();
initialising = false;
self.ready();
self.onStop( function(){
postsHandle.stop();
sharesHandle.stop();
});
});
person
user728291
schedule
11.01.2014