2016-10-02 48 views
0

正如我所说的in another question,我正在研究涉及树的项目。猫鼬:填充一棵树,父亲参照自上而下

  • 的树使用父引用,所以每一个节点都有其母公司的ID
  • 我需要加载从DB树自上而下(从根到儿童)和替换儿童阵列父引用(因为客户端需要它们)
  • 我选择了这种方法,因为我估计98%的操作是在节点上创建/更新(这样我只需要在更新时创建1个节点,而不是更新将父子添加到数组中),只有大约2%是读操作(我只需要读完整树,没有用于读取部分或子树的用例)

树模型是:

const mongoose = require("mongoose"); 
const Promise = require("bluebird"); 
mongoose.Promise = Promise; 
const Node = require("./node-model"); 

const TreeSchema = new mongoose.Schema({ 
    root: { type: Schema.Types.ObjectId, ref: 'Node' }, 
}); 

和节点模型:

const mongoose = require("mongoose"); 
const Promise = require("bluebird"); 
mongoose.Promise = Promise; 

const NodeSchema = new mongoose.Schema({ 
    parent: Schema.Types.ObjectId, 
    children: [], // to be populated on loading the tree 
    data: { 
    d1: String, 
    //... 
    } 
}); 

NodeSchema.methods.populateTree = function() { 
    return this.constructor.find({ parent: this._id }).exec() 
    .then(function(arrayOfChildren) { 
     return Promise.each(arrayOfChildren, function(child){ 
     this.children.push(child); // PROBLEM: 'this' is undfined here! 
     delete child.parent; // delete parent reference because JSON has problems with circular references 
     return child.populateTree(); 
     }); 
    }); 
} 

此外,有一棵树容器:

​​3210

我试图加载完成树(在他的容器中)将其作为JSON发送回客户端,如下所示:

getTreeContainerById = function(req, res) { 
    var promise = TreeContainer. 
    findById(req.params.id). 
    populate("owner", "name"). // only include name 
    populate({ 
     path: "tree", 
     populate: { 
     path: "root", 
     populate: "data" 
     } 
    }).exec(); 

    promise.then(function(treeContainer){ 
     return treeContainer.tree.root.populateTree() 
     .then(function(){ return treeContainer }); 
    }).then(function(treeContainer) { 
     // I need the tree container here to send it back to the client 
     res.json(treeContainer); 
    }); 
}; 

但是这个实现不起作用。我面临的问题是:

  • populateTree架构方法,我无法通过“this”(这是不确定的)访问当前节点,但我需要的参考以某种方式给孩子添加到阵列
  • 如果我尝试child.parent.children.push来代替,这也是行不通的,因为我只有父级的id(在child.parent)而不是实体(并且我不认为这是从数据库再次加载它的正确方法)
  • 在早期版本中,我遇到了问题,即在树完全填充之前JSON被发送回客户端,但我想我解决了这个问题h使用模式方法
  • 一般来说,我不知道,如果这是解决我的问题的正确方法(填充子树引用并删除我的树中的父引用),或者如果有更合适的方法解决方案

我希望我可以明确我的问题。任何帮助深表感谢!

+0

“存在一些问题” - 您能详细说明一下吗? –

+0

@丹尼尔B我编辑了我的文章。如果您还有任何问题,请询问。 – ForceOfWill

+1

'this'的问题很常见,而且很容易解决。看到这里(和许多其他)http://stackoverflow.com/questions/34930771/why-is-this-undefined-inside-class-method-when-using-promises – danh

回答

0

随着populateTree如下原理:

NodeSchema.methods.populateTree = function() { 
    var node = this; 
    return this.constructor.find({ parent: this._id }).exec() 
    .then(function(arrayOfChildren) { 
     return Promise.each(arrayOfChildren, function(child){ 
     node.children.push(child); 
     child.parent = null; 
     return child.populateTree(); 
     }); 
    }); 
} 

感谢@danh谁建议的一样!