第一次通过后返回的递归JavaScript
我有以下递归javascript函数,该函数在backbone.marionete CollectionView的子级上循环,它的子级ItemViews依次是CollectionView:第一次通过后返回的递归JavaScript,javascript,recursion,marionette,Javascript,Recursion,Marionette,我有以下递归javascript函数,该函数在backbone.marionete CollectionView的子级上循环,它的子级ItemViews依次是CollectionView: findViewByCid: function(cid, children){ var col = (arguments.length === 1) ? this.children : children; if(cid in col){ return col[ci
findViewByCid: function(cid, children){
var col = (arguments.length === 1) ? this.children : children;
if(cid in col){
return col[cid];
}
for(child in col){
var grandChildren = col[child].children;
if(cid in grandChildren){
return grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
return this.findViewByCid(cid, grandChildren);
}
}
}
我这样称呼它:
var view=DocumentManager.Documents.treeRoot.findViewByCid(model.cid)
问题在于线路:
return this.findViewByCid(cid, grandChildren);
如果我有这样的层次结构
c1
|_c2
|_c3
|_c4
|_c5
然后te return语句将导致函数在通过th3 c2节点后退出,并且永远不会到达c4等
如果删除return语句,则会找到正确的子级,但返回null
如何继续解析层次结构并返回值?返回将退出函数 尝试将所有内容保存在一个var中,并在最末尾返回,如果需要返回多个值,则可以使用数组。 (不要在for循环中声明变量!) 这里有一个建议:
findViewByCid: function(cid, children){
var willBeReturned=[];
var grandChildren;
var col = (arguments.length === 1) ? this.children : children;
if(cid in col){
willBeReturned[willBeReturned.length] = col[cid];
}
for(child in col){
grandChildren = col[child].children;
if(cid in grandChildren){
willBeReturned[willBeReturned.length] = grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
willBeReturned[willBeReturned.length] = this.findViewByCid(cid, grandChildren);
}
}
return willBeReturned;
}
我相信行if(cid in col)不符合您的要求。试一试
findViewByCid: function(cid, children){
if (this.cid === cid) return this;
var col = (arguments.length === 1) ? this.children : children;
for(var childI in col){
var child = col[childI];
if (child.cid === cid) {
return child;
}
var grandChildren = child.children;
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
return this.findViewByCid(cid, grandChildren);
}
}
}
只有在找到某个对象时才需要返回,否则
return
语句将在没有搜索其他子对象的情况下中断循环。这是一个简单的你想要的
假设函数位于每个子节点的原型上(不仅在根节点上):
或具有将节点作为参数的函数:
function findViewByCid(cid, node) {
var col = node.children;
if (!col)
return false;
if (cid in col)
return col[cid];
for (var child in col) {
var found = findViewByCid(cid, col[child]);
if (found)
return found;
}
return false;
}
但是,该算法似乎无法找到根节点。如果您可以通过cid
识别当前节点,而不是查看其所有子节点,则会更好:
if (this /*… is what we have searched for */)
return this;
首先,它看起来像Backbone.js,如果它是,标记它可能会有所帮助。我觉得人们可能会遇到类似的问题,并且知道更好的方法来存储对视图的引用
你只想在找到东西的时候还它。。。仅在第一次递归调用中使用return将强制该方法在搜索第一组子对象时停止执行,即使没有找到任何内容
我还想在for循环中引入的新变量前面添加一个var,如果没有它,该变量将是全局变量。这就是我最后得到的,它是backbone.marionete,使用collectionView的itemView迭代collectionView:
findViewByCid: function(cid){
var self = this,
ret;
function findView(cid, children){
var col = (arguments.length === 1) ? self.children : children,
grandChildren;
if(cid in col){
ret = col[cid];
}
for(child in col){
grandChildren = col[child].children;
if(cid in grandChildren){
ret = grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
findView(cid, grandChildren);
}
}
};
findView(cid);
return ret;
}
很难解释。考虑CID为5。模型中的cid检查是否存在与模型['cid']==5或model.cid==5不同的模型[5]。它是backbone.marionette,我正在使用一个项目视图迭代CollectionView,该项目视图是CollectionView,这使得它比通常情况下更复杂。
findViewByCid: function(cid, children) {
var col = (arguments.length === 1) ? this.children : children;
if(cid in col){
return col[cid];
}
for(var childKey in col) {
var grandChildren = col[childKey].children,
childView;
if (grandChildren) {
childView = this.findViewByCid(cid, grandChildren);
}
if (childView) {
return childView;
}
}
return null;
}
findViewByCid: function(cid){
var self = this,
ret;
function findView(cid, children){
var col = (arguments.length === 1) ? self.children : children,
grandChildren;
if(cid in col){
ret = col[cid];
}
for(child in col){
grandChildren = col[child].children;
if(cid in grandChildren){
ret = grandChildren[cid];
}
if(grandChildren && (!jQuery.isEmptyObject(grandChildren))){
findView(cid, grandChildren);
}
}
};
findView(cid);
return ret;
}