您好,我递归地枚举了tree
值,并且树中的某些nodes
是undefined
时,我已经设置了防护措施,以确保它不会失败。即使{{1 }}-map
节点出现错误:
输出错误
children
代码
Adrian has children:Marian,Dan,
Dan is leaf
Marian has children:Liviu,Farcas,
t.ngfactory.js?
[sm]:1 ERROR TypeError: Cannot read property 'logRecursive' of undefined
at push../src/app/pages/tree-view/treeview.component.ts.TreeViewComponent.logRecursive (tree-view.component.ts:29)
at Array.map (<anonymous>)
at TreeViewComponent.push../src/app/pages/tree-view/tree-view.component.ts.TreeViewComponent.logRecursive (tree-view.component.ts:29)
at TreeViewComponent.push../src/app/pages/tree-view/tree-view.component.ts.TreeViewComponent.ngOnInit (tree-view.component.ts:37)
at checkAndUpdateDirectiveInline (core.js:18537)
at checkAndUpdateNodeInline (core.js:19801)
at checkAndUpdateNode (core.js:19763)
at debugCheckAndUpdateNode (core.js:20397)
at debugCheckDirectivesFn (core.js:20357)
at Object.eval [as updateDirectives] (TreeViewComponent_Host.ngfactory.js? [sm]:1)
模型
public logRecursive(model:TreeModel):number{
if(model==null || model ==undefined){
console.log("null");
return 0;
}
if(model.children ==undefined || model.children.length==0 ){
console.log(`${model.id} is leaf`);
return 1;
}
console.log(`${model.id} has children:${model.children.reduce((x,y)=>y.id+","+x,"")}`);
var result= model.children.map(this.logRecursive).reduce((x,y)=>x+y);
return result;
}
PS 我已经尝试了export interface TreeModel{
id:string;
children:Array<TreeModel>;
}
是children
,null
或普通undefined
的所有可能的后卫组合,但仍然没有在第一级失败。在第二级失败(length==0
输入
children of 'Marian')
致电
let a:TreeModel={
id:"Adrian",
children:[
{id:"Dan",children:[]},
{id:"Marian",children:[ //fails when mapping his children...
{id:"Farcas",children:[]},
{id:"Liviu",children:[]}
]}
]
};
答案 0 :(得分:1)
问题在于调用this
中的this.logRecursive
是递归调用中的undefined
。原因是在Javascript(以及扩展名Typescript)中,this
不是由函数声明决定的,而是由调用者决定的。因此,调用者可以使用所需的任何this
来调用成员函数。
当您将this.logRecursive
传递给map
时,map
将决定用什么this
来呼叫logRecursive
。 map
不会将任何this
传递给您的函数,从而导致错误。
可以通过在将函数传递给this.logRecursive.bind(this)
时调用map
来解决问题,以解决this
是谁的问题。我不建议在Typescript中使用此功能,因为目前bind
的输入类型非常弱(使用此PR,它很快会在3.2中变得更好)
另一种选择是使用箭头函数,该函数将从声明上下文中捕获this
。
interface TreeModel {
id: string;
children: Array<TreeModel>;
}
let a: TreeModel = {
id: "Adrian",
children: [
{ id: "Dan", children: [] },
{
id: "Marian", children: [ //fails when mapping his children...
{ id: "Farcas", children: [] },
{ id: "Liviu", children: [] }
]
}
]
};
class Comp {
logRecursive(model: TreeModel): number {
if (model == null || model == undefined) {
console.log("null");
return 0;
}
if (model.children == undefined || model.children.length == 0) {
console.log(`${model.id} is leaf`);
return 1;
}
console.log(`${model.id} has children:${model.children.reduce((x, y) => y.id + "," + x, "")}`);
var result = model.children.map(m => this.logRecursive(m)).reduce((x, y) => x + y);
return result;
}
}