我有一个Tag集合,它们只有一个值是标签。它们可以是随机标签或树标签(这里是没有_id
的样本):
{
"label": "/test1"
}
{
"label": "/test2"
}
{
"label": "/test1/test1-1"
}
{
"label": "/test2/test2-1"
}
{
"label": "/test1/test1-1/test1-1-1"
}
{
"label": "something"
}
我想要的是在我的标签树上有一个单独的对象:
{
"/test1": {
"name": "test1"
, "children": {
"/test1/test1-1" : {
"name": "test1-1"
, "children": {
"/test1/test1-1/test1-1-1" : {
"name": "test1-1-1"
, "children": {}
}
}
}
}
}
, "/test2": {
"name": "test2"
, "children": {
"/test2/test1-2" : {
"name": "test1-2"
, "children": {}
}
}
}
}
以下是我在我的应用中尝试的内容:
app.get('/tree', function(req, res, next) {
var tree = {};
Tag
// If you have a better solution, I'm not really fan of this
.$where('this.label.split(new RegExp("/")).length === 2')
.exec(function(err, tags) {
tags.forEach(function(tag) {
tag.getChildren(function(children) {
tree[tag.label] = {
'title': tag.label
, 'children': children
}
});
});
});
// do some stuff with the `tree` var
// which does not work because of the asynchronousity of mongo
});
在我的模型中,它不起作用,起初我想用tag.getChildren()
返回树的路径但是,我认为回调将是更好的选择,我停在那里
Tag.methods.getChildren = function(callback) {
var tree = {};
Tag
.$where('this.label.split(new RegExp("' + this.label + '/")).length === 2')
.exec(function(err, tags) {
tags.forEach(function(tag) {
tag.getChildren(function(children) {
tree[tag.label] = {
'title': tag.label
, 'children': children
}
});
});
return tree
});
};
我不知道怎么做到这一点,我对Node和异步编程都很陌生,所以任何帮助都会受到欢迎。
答案 0 :(得分:1)
您可能应该查看async.js模块,该模块支持执行迭代,在每个步骤调用异步代码并在完成所有异步代码时执行回调。
答案 1 :(得分:1)
在这个例子中做多个Mongo请求是愚蠢的,所以我只做了一个,解析结果并创建我的树,如果有人遇到同样的问题,这是我的代码:
app.get('/tree', function(req, res, next) {
var tree = {}
Tag
.find({ label: { $regex: /^\// } }, ['label'])
// Skip the "/"
.skip(1)
.exec(function(err, tags) {
tags.forEach(function(tag) {
var split = tag.label.split('/');
// Root
if (split.length === 2) {
tree[_.slugify(split[1])] = {
title: split[1]
, children: {}
}
} else {
var name = split.pop()
, path = tag.label
, pathSlug = _.slugify(path.replace(/\//g, '-'))
, parentPath = path.split('/')
, parentSlug = ''
, parent;
parentPath.shift();
parentPath.pop();
parentPath.forEach(function(step) {
step = parentSlug ? parentSlug + '-' + _.slugify(step) : _.slugify(step);
parentSlug = step;
parent = parent ? parent.children[step] : tree[step];
});
if (!parent) {
console.error('ERROR :')
console.log(tag.label)
console.log(path.split('/'))
console.log(name)
console.error('##################')
} else {
parent.children[pathSlug] = {
title: name
, children: {}
}
}
}
});
res.send(tree, 200);
});
});