2016-10-02 45 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誰建議的一樣!