重叠的流星出版物
Overlapping Meteor publications
我有一个 meteor 应用程序,它有 2 个发布的帖子。一个用于所有帖子,一个用于精选帖子。有 2 个精选帖子 - "Post 1" 和 "Post 4"。我在所有页面上显示精选帖子,同时我对所有帖子(包括精选帖子)按名称排序进行分页。当我在页面之间移动时,来自 2 个出版物的数据混淆并显示不正确的结果。
代码如下:
Meteor.publish('posts', function(page) {
const skip = parseInt(page && page !== '' ? page : 0) * 3
return Posts.find({}, {
limit: 3,
skip,
sort: {
name: 1
}
});
});
Meteor.publish('featured', function() {
return Posts.find({
featured: true
}, {
sort: {
name: 1
}
});
});
在客户端上,我订阅了两者并在 2 个循环中显示数据
Template.hello.onCreated(function helloOnCreated() {
const instance = this;
instance.autorun(function() {
instance.subscribe('posts', FlowRouter.getParam('page'))
instance.subscribe('featured')
});
});
Template.hello.helpers({
posts() {
return Posts.find({}, {
limit: 3,
sort: {
name: 1
}
})
},
featured_posts() {
return Posts.find({
featured: true
}, {
sort: {
name: 1
}
});
}
});
HTML模板如下:
<template name="hello">
<h2>Featured</h2>
{{#each featured_posts}}
{{> post}}
{{/each}}
<h2>Posts</h2>
{{#each posts}}
{{> post}}
{{/each}}
</template>
问题是来自 2 个订阅的数据在显示中混淆了。
第 1 页显示正确:
Page 1
Featured
post 1
post 4
All Posts
post 1
post 2
post 3
但是当我转到第 2 页时
Page 2
Featured
post 1
post 4
All Posts -- Should be
post 1 post 4
post 4 post 5
post 5 post 6
它在 "posts" 中显示 "post 1",这是特色但不应出现在第 2 页上。当我转到第 3 页时,我看到 "post 1" 和 "post 4" 但他们不应该在那里。
我了解发布和订阅的工作原理以及发生这种情况的原因 - 因为发布合并了数据集。我想知道是否有办法将它们分开?
如果我理解正确,您的页面对应于您的 "All Posts" 列表的分页。 "page" 号码作为您的订阅参数发送,以便您收到您的帖子的简短列表。
这里的困难确实是你的客户集合没有你手头的所有文件(因为你在你的 'posts'
出版物中限制了它们),所以你不能使用类似的 skip
逻辑在出版物中。
如 Meteor Guide 中所提议 > Paginating subscriptions, you could use the percolate:find-from-publication
Atmosphere 包可轻松检索来自您的 'posts'
出版物的文档,并且仅检索它们。
// Server
FindFromPublication.publish('posts', function(page) {
// Same logic
const skip = parseInt(page && page !== '' ? page : 0) * 3
return Posts.find({}, {
limit: 3,
skip,
sort: {
name: 1
}
});
});
// Client (no change in subscription)
Template.hello.helpers({
posts() {
return Posts.findFromPublication('posts', {}, {
sort: {
name: 1
}
});
} // (no change in featured_posts)
});
我建议使用 observe
or observeChanges
以便可以在客户端隔离正在发布的数据。文档可能令人生畏,但实际上比看起来容易。
只需创建一个特殊的客户端集合,然后在观察回调中使用该集合的名称即可。请注意,在发布中对 self.added
、self.changed
和 self.removed
的调用中使用了客户端集合名称 "featured_posts"
:
// client-side
const FeaturedPosts = new Mongo.Collection('featured_posts', {
defineMutationMethods: false
});
// server-side
Meteor.publish('featured', function() {
const self = this;
const handle = collection.find(selector, opts).observe({
added: function(doc) {
self.added('featured_posts', doc._id, doc);
},
changed: function(newDoc, oldDoc) {
self.changed('featured_posts', newDoc._id, newDoc);
},
removed: function(doc) {
self.removed('featured_posts', doc._id);
},
});
self.ready();
self.onStop(function(err) {
if (!err) {
handle.stop();
}
});
});
};
我有一个 meteor 应用程序,它有 2 个发布的帖子。一个用于所有帖子,一个用于精选帖子。有 2 个精选帖子 - "Post 1" 和 "Post 4"。我在所有页面上显示精选帖子,同时我对所有帖子(包括精选帖子)按名称排序进行分页。当我在页面之间移动时,来自 2 个出版物的数据混淆并显示不正确的结果。
代码如下:
Meteor.publish('posts', function(page) {
const skip = parseInt(page && page !== '' ? page : 0) * 3
return Posts.find({}, {
limit: 3,
skip,
sort: {
name: 1
}
});
});
Meteor.publish('featured', function() {
return Posts.find({
featured: true
}, {
sort: {
name: 1
}
});
});
在客户端上,我订阅了两者并在 2 个循环中显示数据
Template.hello.onCreated(function helloOnCreated() {
const instance = this;
instance.autorun(function() {
instance.subscribe('posts', FlowRouter.getParam('page'))
instance.subscribe('featured')
});
});
Template.hello.helpers({
posts() {
return Posts.find({}, {
limit: 3,
sort: {
name: 1
}
})
},
featured_posts() {
return Posts.find({
featured: true
}, {
sort: {
name: 1
}
});
}
});
HTML模板如下:
<template name="hello">
<h2>Featured</h2>
{{#each featured_posts}}
{{> post}}
{{/each}}
<h2>Posts</h2>
{{#each posts}}
{{> post}}
{{/each}}
</template>
问题是来自 2 个订阅的数据在显示中混淆了。
第 1 页显示正确:
Page 1
Featured
post 1
post 4
All Posts
post 1
post 2
post 3
但是当我转到第 2 页时
Page 2
Featured
post 1
post 4
All Posts -- Should be
post 1 post 4
post 4 post 5
post 5 post 6
它在 "posts" 中显示 "post 1",这是特色但不应出现在第 2 页上。当我转到第 3 页时,我看到 "post 1" 和 "post 4" 但他们不应该在那里。
我了解发布和订阅的工作原理以及发生这种情况的原因 - 因为发布合并了数据集。我想知道是否有办法将它们分开?
如果我理解正确,您的页面对应于您的 "All Posts" 列表的分页。 "page" 号码作为您的订阅参数发送,以便您收到您的帖子的简短列表。
这里的困难确实是你的客户集合没有你手头的所有文件(因为你在你的 'posts'
出版物中限制了它们),所以你不能使用类似的 skip
逻辑在出版物中。
如 Meteor Guide 中所提议 > Paginating subscriptions, you could use the percolate:find-from-publication
Atmosphere 包可轻松检索来自您的 'posts'
出版物的文档,并且仅检索它们。
// Server
FindFromPublication.publish('posts', function(page) {
// Same logic
const skip = parseInt(page && page !== '' ? page : 0) * 3
return Posts.find({}, {
limit: 3,
skip,
sort: {
name: 1
}
});
});
// Client (no change in subscription)
Template.hello.helpers({
posts() {
return Posts.findFromPublication('posts', {}, {
sort: {
name: 1
}
});
} // (no change in featured_posts)
});
我建议使用 observe
or observeChanges
以便可以在客户端隔离正在发布的数据。文档可能令人生畏,但实际上比看起来容易。
只需创建一个特殊的客户端集合,然后在观察回调中使用该集合的名称即可。请注意,在发布中对 self.added
、self.changed
和 self.removed
的调用中使用了客户端集合名称 "featured_posts"
:
// client-side
const FeaturedPosts = new Mongo.Collection('featured_posts', {
defineMutationMethods: false
});
// server-side
Meteor.publish('featured', function() {
const self = this;
const handle = collection.find(selector, opts).observe({
added: function(doc) {
self.added('featured_posts', doc._id, doc);
},
changed: function(newDoc, oldDoc) {
self.changed('featured_posts', newDoc._id, newDoc);
},
removed: function(doc) {
self.removed('featured_posts', doc._id);
},
});
self.ready();
self.onStop(function(err) {
if (!err) {
handle.stop();
}
});
});
};