0

Tagコレクションがあります。ラベルという値は1つだけです。それらはランダムタグまたはツリータグ(ここでは_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
    });
};

これを行う方法がわかりません。ノードと非同期プログラミングはかなり新しいので、助けていただければ幸いです。

4

2 に答える 2

1

おそらく、async.jsモジュールを調べる必要があります。このモジュールは、各ステップで非同期コードを呼び出す反復を実行し、すべての非同期コードが完了したときにコールバックを実行するためのサポートを備えています。

于 2012-08-07T11:00:44.710 に答える
1

この例では、複数のMongoリクエストを実行するのはばかげているので、1つだけ実行し、結果を解析してツリーを作成します。誰かが同じ問題を抱えている場合のコードは次のとおりです。

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);
    });
});
于 2012-08-08T09:20:49.143 に答える