流星数据隔离
Meteor data isolation
如何隔离模板之间的订阅数据?
例如 - 我的一页有两个 不同的 模板:
1) 主题列表
2) 热门话题。
我有两个 不同的 Meteor.publish 和订阅。
1) 在主题列表模板中,我已按 CreatedAt 字段排序。
Meteor.subscribe('topics');
Template.topics_main.helpers({
topics:function(){
return Topic.find({},{sort: {createdAt: -1}});
}
});
2) 在热门列表中,我按评级字段对数据进行排序。
Meteor.subscribe('popularTopics');
Template.top_topics.helpers({
topics:function(){
return Topic.find({}, {
sort: {
views: -1
},
limit: 5
});
}
});
当我滚动主题列表时,我将从热门主题中获取数据。这不好 :) 我如何隔离两个具有不同订阅但属于一种集合的模板之间的数据?
这是 Meteor 当前发布模型的已知限制。
想到的一些克服此问题的选项:
- 找到一种使用更精确的查询来区分数据的方法。
- 以另一种方式获取一些数据(例如,使用一种方法,而不使用 pub/sub 或集合)。
- 发布到 "virtual" 集合(通过手动监控发布中的游标)。
Apollo Stack 也可以派上用场。
observeChanges 可能就是您所需要的。它允许您将文档发布到特定集合,因此您可以让您的两个发布(topics
和 popularTopics
)从服务器上的同一个集合(Topics
)中获取数据,但是将其发送到客户端上的不同集合(例如 Topics
和 PopularTopics
)。
这是一个例子:
// globally somewhere
const Topics = new Mongo.Collection('topics');
const PopularTopics = new Mongo.Collection('populartopics');
添加您的出版物,observeChanges 将已发布的文档发送到客户端上的两个不同集合:
// topics.publications.js
const abstractPublish = function (collectionName, query) {
const cursor = Topics.find(query);
const cursorHandle = cursor.observeChanges({
added(id, fields) {
this.added(collectionName, id, fields);
},
changed(id, fields) {
this.changed(collectionName, id, fields);
},
removed(id) {
this.removed(collectionName, id);
}
});
this.onStop(()=>{
if (cursorHandle) cursorHandle.stop();
});
this.ready();
};
Meteor.publish('topics', function () {
// set up a publication to the "topics" collection
abstractPublish.call(this, 'topics', {});
});
Meteor.publish('popularTopics', function () {
// set up a publication to the "populartopics" collection
abstractPublish.call(this, 'populartopics', {popular: true});
});
然后设置您的模板级订阅:
// topics_main.js
Template.topics_main.onCreated(function () {
this.autorun(() => {
this.subscribe('topics', function () {
Topics.find().fetch(); // returns all topics
);
});
});
在您的热门主题模板中:
// top_topics.js
Template.top_topics.onCreated(function () {
this.autorun(() => {
this.subscribe('popularTopics', function () {
PopularTopics.find().fetch(); // returns only topics that have {popular: true}
);
});
});
如何隔离模板之间的订阅数据?
例如 - 我的一页有两个 不同的 模板:
1) 主题列表
2) 热门话题。
我有两个 不同的 Meteor.publish 和订阅。
1) 在主题列表模板中,我已按 CreatedAt 字段排序。
Meteor.subscribe('topics');
Template.topics_main.helpers({
topics:function(){
return Topic.find({},{sort: {createdAt: -1}});
}
});
2) 在热门列表中,我按评级字段对数据进行排序。
Meteor.subscribe('popularTopics');
Template.top_topics.helpers({
topics:function(){
return Topic.find({}, {
sort: {
views: -1
},
limit: 5
});
}
});
当我滚动主题列表时,我将从热门主题中获取数据。这不好 :) 我如何隔离两个具有不同订阅但属于一种集合的模板之间的数据?
这是 Meteor 当前发布模型的已知限制。
想到的一些克服此问题的选项:
- 找到一种使用更精确的查询来区分数据的方法。
- 以另一种方式获取一些数据(例如,使用一种方法,而不使用 pub/sub 或集合)。
- 发布到 "virtual" 集合(通过手动监控发布中的游标)。
Apollo Stack 也可以派上用场。
observeChanges 可能就是您所需要的。它允许您将文档发布到特定集合,因此您可以让您的两个发布(topics
和 popularTopics
)从服务器上的同一个集合(Topics
)中获取数据,但是将其发送到客户端上的不同集合(例如 Topics
和 PopularTopics
)。
这是一个例子:
// globally somewhere
const Topics = new Mongo.Collection('topics');
const PopularTopics = new Mongo.Collection('populartopics');
添加您的出版物,observeChanges 将已发布的文档发送到客户端上的两个不同集合:
// topics.publications.js
const abstractPublish = function (collectionName, query) {
const cursor = Topics.find(query);
const cursorHandle = cursor.observeChanges({
added(id, fields) {
this.added(collectionName, id, fields);
},
changed(id, fields) {
this.changed(collectionName, id, fields);
},
removed(id) {
this.removed(collectionName, id);
}
});
this.onStop(()=>{
if (cursorHandle) cursorHandle.stop();
});
this.ready();
};
Meteor.publish('topics', function () {
// set up a publication to the "topics" collection
abstractPublish.call(this, 'topics', {});
});
Meteor.publish('popularTopics', function () {
// set up a publication to the "populartopics" collection
abstractPublish.call(this, 'populartopics', {popular: true});
});
然后设置您的模板级订阅:
// topics_main.js
Template.topics_main.onCreated(function () {
this.autorun(() => {
this.subscribe('topics', function () {
Topics.find().fetch(); // returns all topics
);
});
});
在您的热门主题模板中:
// top_topics.js
Template.top_topics.onCreated(function () {
this.autorun(() => {
this.subscribe('popularTopics', function () {
PopularTopics.find().fetch(); // returns only topics that have {popular: true}
);
});
});