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;
}
})
});
}
示范:
我编写了一个函数,从我的对象数组(最喜欢的玩家)中获取并显示 "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;
}
})
});
}
示范: