Angular2:TypeError'this。'未定义

时间:2017-06-10 12:53:28

标签: function angular typescript routing angular2-routing

我写了一个函数,从我的对象数组(最喜欢的玩家)中获取并显示“最佳玩家”。该功能正常工作并向我显示我想要的内容,但浏览器在控制台中显示错误,并且我的应用程序中的路由被阻止(我无法使用路由在组件之间导航)

这是我的DashboardComponent类

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]未定义   错误:未捕获(在承诺中):错误:无法激活已激活的插座   错误:未捕获(在承诺中):错误:无法激活已激活的插座

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

请帮忙!

3 个答案:

答案 0 :(得分:3)

作为旁注,总是当你提供一个吸油烟机时,确保它是一个有效的;)当我开始工作时,实际上只有几个问题。您的路由没有任何问题。你得到的第一个错误

  

this.data [i]未定义

是因为你的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

答案 1 :(得分:1)

问题出在您的服务上,

您正在尝试循环播放不可用的数据,

您需要更改代码, 如果您使用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];
      }
    })

答案 2 :(得分:1)

Assalamualaikum,

我修复了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;
      }
    }) 
  });
}

我真的希望这可以帮助你Hamdi,并祝你项目一切顺利,如果你有任何问题,请告诉我,我会非常乐意提供帮助 enter image description here

Ramadan Mubarak。