递归发布 - Angular-meteor
Recursive Publishing - Angular-meteor
我想加载一个主题、它的 25 条评论和每条评论最多 5 条子评论,对每个评论重复递归 comment/sub-comment 直到找到所有相关评论。
我目前正在使用 angular 指令递归订阅并在评论有 children 时添加到本地集合。它工作得很好,但在加载最初的 25 条评论和加载它们的 children,然后它们的 children 等等之间存在一些延迟(可以预料)。
如果一次只加载一个页面,这个问题不是问题。当使用无限滚动并增加最初的 25 条评论限制时,这会成为一个问题。当子评论消失并再次加载后重新出现时,它会导致页面上下跳动。
我想知道如何在发送给本地客户端之前递归地查找所有评论,这样我就不需要为每个主题进行多次往返。
加载了一个演示
如果您滚动到底部,它将加载更多内容,并且您会看到它在子评论重新加载到页面时跳到整个页面。
我能想到的两个选项是在加载页面之前使用解析等待所有集合,或者使用递归发布首先获取它们。
想法?想法?
好的,我的第一次尝试,如果可能的话,我想谈谈一些想法。
对于发布,我决定使用 publish-composite 以便更容易地从同一个集合中发布。
我写的出版物:
Meteor.publishComposite('oneDiscussion', function (slug, options) {
var query = {};
query.find = function () {
return Discussions.find({ slug: slug }, { limit: 1 });
};
var mainChildQuery = Comments.find({ slug: slug }, { limit: 1 });
query.children = [];
query.children[0] = {};
query.children[0].find = function (discussion) {
return mainChildQuery;
};
query.children[0].children = [];
query.children[0].children[0] = {};
query.children[0].children[0].find = function (comment) {
return Meteor.users.find({ _id: comment.author.id }, { limit: 1, fields: { profile: 1, roles: 1, createdAt: 1, username: 1 } });
};
query.children[0].children[1] = {};
query.children[0].children[1].find = function (parent) {
Counts.publish(this, 'numberOfComments', Comments.find(
{ parent_id: parent._id }
), { noReady: true });
console.log(options)
return Comments.find({ parent_id: parent._id }, options);
};
// var parentQuery = Comments.find({ slug: slug });
var parent = mainChildQuery.fetch();
var children = Comments.find({ parent_id: parent[0]._id }, { limit: 25 }).fetch();
var childrenIds = _.pluck(children, '_id');
var getChildren = function (children_ids, thisParent) {
var i = 0;
thisParent.children = [];
var recursive = function getEm(children, parent) {
_.each(children, function (id) {
// parent.children[i] = new Children(id);
var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
parent.children[i] = {
find: function () {
return Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
}
};
var children1 = query.fetch();
var newChildrenIds = _.pluck(children1, '_id');
i++;
if (newChildrenIds.length > 0) {
getEm(newChildrenIds, parent);
}
});
}
recursive(children_ids, thisParent);
};
getChildren(childrenIds, query.children[0].children[1]);
return query;
});
到目前为止似乎工作正常,但 运行 它在我的桌面上的性能不如我想象的那么好。我会部署它,看看是否有在线差异。我会在回家时更新并且可以更新实时站点。如果有人能发现我写的东西有问题,将不胜感激。
我想出了我认为最好的解决方案。我改进了上面的功能,到目前为止我真的很喜欢结果。
这里是发布函数:
Meteor.publishComposite('comments', function (item_id, options) {
/**
* TODO: Add query to find a user for each comment.
*/
/**
* Start building our query.
* Add the latest 25 (depending on options) child comments of the viewed item
* to the query.
*/
var query = {
find: function () {
return Comments.find({ parent_id: item_id }, options);
}
};
// Query the database for the first 25? comments, we'll need their _id's
var mainChildren = Comments.find({ parent_id: item_id }, options).fetch();
// pluck the id's from the initial comments
var mainChildrenIds = _.pluck(mainChildren, '_id');
/**
* Builds the remaining query based on the id's plucked from the children
* above.
* @param childrens_id The id's we just plucked from the above query
* @param thisParent This is the parent query
*/
var getChildren = function (children_ids, parentQuery) {
// initiate i to 0
var i = 0;
// add a child array to the current parent query.
parentQuery.children = [];
var recursive = function getem(children, parent) {
_.each(children, function (id) {
var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: 1 } });
parent.children[i] = {
find: function () {
return query;
}
};
var children1 = query.fetch();
var newChildrenIds = _.pluck(children1, '_id');
i++;
if (newChildrenIds.length > 0) {
getem(newChildrenIds, parent);
}
});
};
// recursively build the query if there are children found.
recursive(children_ids, parentQuery);
};
// initiate the query build function
getChildren(mainChildrenIds, query);
return query;
});
我创建了一个示例应用程序,您可以在 GitHub here
你可以在 meteorpad 运行 上查看 here
它的作用
该函数所做的就是构建 publishComposite 查询,递归循环遍历 children 个 ID,只要有 children 个 ID。当没有更多 children 时它停止。
使用它
您想要一组具有 parent_id 字段的评论(或您嵌套的任何内容)。此字段将填充 parent post Id,parent 项目 ID(如果说用 reviews/comments 建立商店)。 parent post id 当然是您正在评论的评论或 post。有关详细信息,请参阅示例。
我想加载一个主题、它的 25 条评论和每条评论最多 5 条子评论,对每个评论重复递归 comment/sub-comment 直到找到所有相关评论。
我目前正在使用 angular 指令递归订阅并在评论有 children 时添加到本地集合。它工作得很好,但在加载最初的 25 条评论和加载它们的 children,然后它们的 children 等等之间存在一些延迟(可以预料)。
如果一次只加载一个页面,这个问题不是问题。当使用无限滚动并增加最初的 25 条评论限制时,这会成为一个问题。当子评论消失并再次加载后重新出现时,它会导致页面上下跳动。
我想知道如何在发送给本地客户端之前递归地查找所有评论,这样我就不需要为每个主题进行多次往返。
加载了一个演示如果您滚动到底部,它将加载更多内容,并且您会看到它在子评论重新加载到页面时跳到整个页面。
我能想到的两个选项是在加载页面之前使用解析等待所有集合,或者使用递归发布首先获取它们。
想法?想法?
好的,我的第一次尝试,如果可能的话,我想谈谈一些想法。
对于发布,我决定使用 publish-composite 以便更容易地从同一个集合中发布。
我写的出版物:
Meteor.publishComposite('oneDiscussion', function (slug, options) {
var query = {};
query.find = function () {
return Discussions.find({ slug: slug }, { limit: 1 });
};
var mainChildQuery = Comments.find({ slug: slug }, { limit: 1 });
query.children = [];
query.children[0] = {};
query.children[0].find = function (discussion) {
return mainChildQuery;
};
query.children[0].children = [];
query.children[0].children[0] = {};
query.children[0].children[0].find = function (comment) {
return Meteor.users.find({ _id: comment.author.id }, { limit: 1, fields: { profile: 1, roles: 1, createdAt: 1, username: 1 } });
};
query.children[0].children[1] = {};
query.children[0].children[1].find = function (parent) {
Counts.publish(this, 'numberOfComments', Comments.find(
{ parent_id: parent._id }
), { noReady: true });
console.log(options)
return Comments.find({ parent_id: parent._id }, options);
};
// var parentQuery = Comments.find({ slug: slug });
var parent = mainChildQuery.fetch();
var children = Comments.find({ parent_id: parent[0]._id }, { limit: 25 }).fetch();
var childrenIds = _.pluck(children, '_id');
var getChildren = function (children_ids, thisParent) {
var i = 0;
thisParent.children = [];
var recursive = function getEm(children, parent) {
_.each(children, function (id) {
// parent.children[i] = new Children(id);
var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
parent.children[i] = {
find: function () {
return Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
}
};
var children1 = query.fetch();
var newChildrenIds = _.pluck(children1, '_id');
i++;
if (newChildrenIds.length > 0) {
getEm(newChildrenIds, parent);
}
});
}
recursive(children_ids, thisParent);
};
getChildren(childrenIds, query.children[0].children[1]);
return query;
});
到目前为止似乎工作正常,但 运行 它在我的桌面上的性能不如我想象的那么好。我会部署它,看看是否有在线差异。我会在回家时更新并且可以更新实时站点。如果有人能发现我写的东西有问题,将不胜感激。
我想出了我认为最好的解决方案。我改进了上面的功能,到目前为止我真的很喜欢结果。
这里是发布函数:
Meteor.publishComposite('comments', function (item_id, options) {
/**
* TODO: Add query to find a user for each comment.
*/
/**
* Start building our query.
* Add the latest 25 (depending on options) child comments of the viewed item
* to the query.
*/
var query = {
find: function () {
return Comments.find({ parent_id: item_id }, options);
}
};
// Query the database for the first 25? comments, we'll need their _id's
var mainChildren = Comments.find({ parent_id: item_id }, options).fetch();
// pluck the id's from the initial comments
var mainChildrenIds = _.pluck(mainChildren, '_id');
/**
* Builds the remaining query based on the id's plucked from the children
* above.
* @param childrens_id The id's we just plucked from the above query
* @param thisParent This is the parent query
*/
var getChildren = function (children_ids, parentQuery) {
// initiate i to 0
var i = 0;
// add a child array to the current parent query.
parentQuery.children = [];
var recursive = function getem(children, parent) {
_.each(children, function (id) {
var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: 1 } });
parent.children[i] = {
find: function () {
return query;
}
};
var children1 = query.fetch();
var newChildrenIds = _.pluck(children1, '_id');
i++;
if (newChildrenIds.length > 0) {
getem(newChildrenIds, parent);
}
});
};
// recursively build the query if there are children found.
recursive(children_ids, parentQuery);
};
// initiate the query build function
getChildren(mainChildrenIds, query);
return query;
});
我创建了一个示例应用程序,您可以在 GitHub here
你可以在 meteorpad 运行 上查看 here
它的作用
该函数所做的就是构建 publishComposite 查询,递归循环遍历 children 个 ID,只要有 children 个 ID。当没有更多 children 时它停止。
使用它
您想要一组具有 parent_id 字段的评论(或您嵌套的任何内容)。此字段将填充 parent post Id,parent 项目 ID(如果说用 reviews/comments 建立商店)。 parent post id 当然是您正在评论的评论或 post。有关详细信息,请参阅示例。