Angular2:TypeError 'this.' 未定义

Angular2 : TypeError 'this.' is undefined

我编写了一个函数,从我的对象数组(最喜欢的玩家)中获取并显示 "best player"。该功能运行良好并显示了我想要的内容,但浏览器在控制台中显示错误,并且我的应用程序中的路由被阻止(我无法使用路由在组件之间导航)

这是我的 DashboardComponent Class

export class DashboardComponent implements OnInit {
  bestPlayer:Player;
  data:Player[]=[];
  max:number =0;
  constructor(private playerService : PlayerService ,private router: Router) { }

  ngOnInit() { 
    this.playerService.getData().then(data => {
      this.data = data;
      for (var i = 0; i <= this.data.length; i++) {
        if (this.data[i].likes>this.max) {
          this.max=this.data[i].likes;
          this.bestPlayer=this.data[i];
        }
      }
    });  
  }

  viewDetails(bestPlayer: Player):void {
    this.router.navigate(['/detail',this.bestPlayer.id]);
  }
}

这是我的服务:

import {Player} from './player';
import {PlayersData} from './muck-players';
import { Injectable } from '@angular/core';

@Injectable()
export class PlayerService {
  players:any;
  data:any;
  Player:Player;

  getData():Promise <Player[]> {
    return Promise.resolve(PlayersData);
  }
}

当我 运行 应用程序时,浏览器向我显示这些错误:

TypeError: this.data[i] is undefined Error: Uncaught (in promise): Error: Cannot activate an already activated outlet Error: Uncaught (in promise): Error: Cannot activate an already activated outlet

当我删除 ngOninit()viewDetails() 函数中的内容时,路由再次开始工作并且浏览器不显示错误。

请帮忙!

您好,问题出在您的服务上,

您正在尝试循环访问不可用的数据,

您需要更改代码, 如果您使用 Observer 作为服务,那么将您的代码放入 .subscribe 方法中,

如果您使用的是 promise,则将循环代码放在 .then() 方法中。

尝试使用这个:

如果您从 this.playerService.getData() 此服务返回承诺

this.playerService.getData().then((data) => {
 this.data = data;
 for (var i = 0; i <= this.data.length; i++) {
    if (this.data[i].likes>this.max) {
      this.max=this.data[i].likes;
      this.bestPlayer=this.data[i];


  }
})

如果您从 this.playerService.getData() 此服务返回 observable

   this.playerService.getData().subscribe((data) => {
     this.data = data;
     for (var i = 0; i <= this.data.length; i++) {
        if (this.data[i].likes>this.max) {
          this.max=this.data[i].likes;
          this.bestPlayer=this.data[i];
      }
    })

作为旁注,当你提供一个 plunker 时,请确保它是一个工作的 ;) 当我让它工作时,实际上只有几个问题。你的路由没有问题。您遇到的第一个错误

this.data[i] is undefined

是因为你的 for 循环,你已经标记我们应该循环直到 i 匹配数组的长度(或等于)。但是我们需要记住数组的索引以0开头。所以最后一次迭代它试图读取数组中不存在的索引。所以你应该将 -1 添加到你的 for 循环中:

for (var i = 0; i <= this.data.length-1; i++) 

或做

for (var i = 0; i < this.data.length; i++)

修复此问题后,会产生新问题。由于数据是异步的,因此在呈现模板时,您的变量 bestPlayer 未定义。这可以通过 safe navigation operator 来解决,或者将所有内容包装在 div 中,条件是 bestPlayer 具有值。这需要应用于详细信息页面和仪表板。使用仪表板:

<div *ngIf="bestPlayer">
  <!-- code here -->
</div>

在详细信息页面中,相同但使用 player,因为这是您在那里使用的变量。

如前所述,您还可以使用安全导航运算符。

这些实际上清除了您也遇到的第二个错误。

这是你的固定 PLUNKER.

我修复了 Plunker 中的许多错误并添加了一些缺失的路由功能。该应用程序现在运行良好,请查看我的分叉 Plunker over here

我修复了所有文件路径并在组件的 forEach 方法中使用,就像这样:

ngOnInit() { 
  this.playerService.getData().then(data => {
      data.forEach( (arrData) => {
      if (arrData.likes>this.max) {
      this.max=arrData.likes;
      this.bestPlayer=arrData;
      }
    }) 
  });
}

示范: