Сбой карты из-за неопределенного свойства - PullRequest
0 голосов
/ 21 ноября 2018

Здравствуйте, я рекурсивно перечисляю tree значения, и хотя некоторые nodes в дереве undefined, я установил охрану, чтобы он не вышел из строя. Даже когда map -ing 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;
  }

Модель

export interface TreeModel{
    id:string;
    children:Array<TreeModel>;
}

PS Я перепробовал все возможные комбинации защиты для 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:[]}
         ]}
       ]
     };

Вызов logRecursive(a);

1 Ответ

0 голосов
/ 21 ноября 2018

Проблема в том, что this в вызове this.logRecursive равно undefined в рекурсивном вызове.Причина этого заключается в том, что в Javascript (и расширением Typescript) this определяется не объявлением функции, а вызывающей стороной.Таким образом, вызывающая сторона может вызывать функцию-член с любым значением this, которое она хочет.

Когда вы передаете this.logRecursive на map, map будет решать, с каким this позвонить logRecursive.map просто не передаст this вашей функции и, следовательно, ошибке.

Проблема может быть исправлена ​​путем вызова this.logRecursive.bind(this) при передаче функции в map для исправления who this есть.Я не рекомендую это в Typescript, так как bind очень слабо набрано в настоящее время (скоро это улучшится в 3.2 с этим PR )

Другой вариант - использовать функцию стрелки, который захватит 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...