Angular 2 显示数组的具体索引
Angular 2 Display specific index of array
我正在尝试使用以下代码 display/loop 数组中的一个或多个变量。
<tr *ngFor="let ep of theshow.episodes[0]">
不幸的是 angular 不允许我这样做,有没有办法让我只能显示索引为 0 的数组中的数组?
仅供参考:这是我学习的第一个试用个人项目angular 2,所以如果您发现任何其他可以以更好的方式完成的事情,请告诉。
"theshow"变量中的数据如下(googlechromeinspectorcopy/paste)
Object
name: "game of thrones"
airtime: "21:00"
id: 82
episodes: Array[7] //each array contains a season
0: Array[10] //each season contains all there episodes (this is season 1)
0: Object //episode 1
name: "Winter is coming"
...
1: Object //episode 2
name: "The Kingsroad"
...
2: Object //episode 3
name: "Lord Snow"
...
1: Array[10] //season 2
0: Object //episode 11
name: "The North Remembers"
...
1: Object //episode 12
name: "The Night Lands"
...
2: Object //episode 13
name: "What is Dead May Never Die"
...
...
这是我尝试的完整代码运行。
<tr *ngFor="let ep of theshow.episodes[0]">
<td class="mailbox-name">{{ep.name}}</td>
<td class="mailbox-subject">{{ep.airdate}}</td>
<td class="mailbox-date">{{ep.airtime}}</td>
</tr>
我收到的错误消息是:
Uncaught (in promise): Error: Error in ./SearchComponent class SearchComponent - inline template:69:22 caused by: Cannot read property '0' of undefined
TypeError: Cannot read property '0' of undefined
at _View_SearchComponent2.detectChangesInternal (/AppModule/SearchComponent/component.ngfactory.js:555:61)
at _View_SearchComponent2.AppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56393:14)
at _View_SearchComponent2.DebugAppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56498:44)
at _View_SearchComponent0.AppView.detectContentChildrenChanges (http://127.0.0.1:4200/main.bundle.js:56411:19)
at _View_SearchComponent0.detectChangesInternal (/AppModule/SearchComponent/component.ngfactory.js:81:8)
at _View_SearchComponent0.AppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56393:14)
at _View_SearchComponent0.DebugAppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56498:44)
at _View_SearchComponent_Host0.AppView.detectViewChildrenChanges (http://127.0.0.1:4200/main.bundle.js:56419:19)
at _View_SearchComponent_Host0.detectChangesInternal (/AppModule/SearchComponent/host.ngfactory.js:33:8)
at _View_SearchComponent_Host0.AppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56393:14)
serie.service.ts
import { Injectable, Input } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class SerieService {
url = "//api.tvmaze.com/search/shows?q=";
getSerie(id){
this.url = "http://api.tvmaze.com/shows/"+ id +"?embed=episodes";
var re = '';
return this._http.get(this.url).map(this.cleanSerieData);
}
private cleanSerieData(res: Response){
let body = res.json();
var tmp = [];
body._embedded.episodes.forEach(el => {
if(tmp[el.season-1] == undefined){
tmp[el.season-1] = [];
}
tmp[el.season-1].push(el);
});
var clean = {
id: body.id,
name: body.name,
rating: body.rating.average,
airday: body.schedule.days,
airtime: body.schedule.time,
status: body.status,
summary: body.summary,
episodes:tmp,
countSeasons: tmp.length,
countEpisodes: body._embedded.episodes.length
};
return clean;
}
constructor(private _http:Http) { }
}
Search.component.ts
import { Component, OnInit } from '@angular/core';
import { SerieService } from './../serie.service';
import { Router, ActivatedRoute, Params } from '@angular/router';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
srh = '';
shows = [];
tmp = [];
id = undefined;
theshow = {};
search(event:any){
this.srh = event.target.value;
this.serieService.getSeries(this.srh)
.subscribe(res => {
console.log(res);
this.shows = res;
})
}
constructor(
private serieService: SerieService,
private route: ActivatedRoute,
private router: Router
) { }
ngOnInit() {
this.id = this.route.snapshot.params['id'];
this.searchFunction();
}
searchFunction()
{
if(this.id == undefined)
{
console.log('search functie');
}else{
this.serieService.getSerie(this.id).subscribe(res => {
console.log(res);
this.theshow = res;
console.log(res.episodes[0])
});
}
}
}
编辑,添加代码。
最终我的想法是我可以点击第 2 季(按钮)并通过更改为(使用变量 ofc)来获取第 2 季的所有剧集
非常感谢您的回复。
Stefan 的回答很接近,但缺少更新后的关键信息 post。
异步获取确实意味着尚未定义 show 变量上的剧集 属性。
到目前为止,您构建的内容有三种可能的解决方案:
- 将显示变量的初始化从
theshow = {}
更改为 theshow = {episodes: []}
。
- 在渲染之前检查剧集是否存在。守卫没有在我的 plunker 中工作,但是
<table *ngIf="theshow?.episodes"><tr *ngFor="let episode of theshow.episodes[0]">
正在工作(theshow?.episodes?[0]
似乎不是有效的语法)。
- 创建可以实例化为虚拟对象的适当对象
theshow: ShowInformation = new ShowInformation()
,其中您已经适当地定义了 ShowInformation class 并且它正确地将空变量构造为占位符。
- 使用此 QA 中的异步管道,但它需要更多返工以获得更好的长期解决方案:
这是一个硬连线的 plunker 示例(我没有费心去实现搜索、路由等):http://plnkr.co/edit/i0Vx6cLmPyNyavLCwCeY?p=preview
您可以像下面这样操作:
<tr *ngFor="let ep of theshow.episodes">
<td class="mailbox-name">{{ep[0].name}}</td>
<td class="mailbox-subject">{{ep[0].airdate}}</td>
<td class="mailbox-date">{{ep[0].airtime}}</td>
</tr>
我正在尝试使用以下代码 display/loop 数组中的一个或多个变量。
<tr *ngFor="let ep of theshow.episodes[0]">
不幸的是 angular 不允许我这样做,有没有办法让我只能显示索引为 0 的数组中的数组?
仅供参考:这是我学习的第一个试用个人项目angular 2,所以如果您发现任何其他可以以更好的方式完成的事情,请告诉。
"theshow"变量中的数据如下(googlechromeinspectorcopy/paste)
Object
name: "game of thrones"
airtime: "21:00"
id: 82
episodes: Array[7] //each array contains a season
0: Array[10] //each season contains all there episodes (this is season 1)
0: Object //episode 1
name: "Winter is coming"
...
1: Object //episode 2
name: "The Kingsroad"
...
2: Object //episode 3
name: "Lord Snow"
...
1: Array[10] //season 2
0: Object //episode 11
name: "The North Remembers"
...
1: Object //episode 12
name: "The Night Lands"
...
2: Object //episode 13
name: "What is Dead May Never Die"
...
...
这是我尝试的完整代码运行。
<tr *ngFor="let ep of theshow.episodes[0]">
<td class="mailbox-name">{{ep.name}}</td>
<td class="mailbox-subject">{{ep.airdate}}</td>
<td class="mailbox-date">{{ep.airtime}}</td>
</tr>
我收到的错误消息是:
Uncaught (in promise): Error: Error in ./SearchComponent class SearchComponent - inline template:69:22 caused by: Cannot read property '0' of undefined
TypeError: Cannot read property '0' of undefined
at _View_SearchComponent2.detectChangesInternal (/AppModule/SearchComponent/component.ngfactory.js:555:61)
at _View_SearchComponent2.AppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56393:14)
at _View_SearchComponent2.DebugAppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56498:44)
at _View_SearchComponent0.AppView.detectContentChildrenChanges (http://127.0.0.1:4200/main.bundle.js:56411:19)
at _View_SearchComponent0.detectChangesInternal (/AppModule/SearchComponent/component.ngfactory.js:81:8)
at _View_SearchComponent0.AppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56393:14)
at _View_SearchComponent0.DebugAppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56498:44)
at _View_SearchComponent_Host0.AppView.detectViewChildrenChanges (http://127.0.0.1:4200/main.bundle.js:56419:19)
at _View_SearchComponent_Host0.detectChangesInternal (/AppModule/SearchComponent/host.ngfactory.js:33:8)
at _View_SearchComponent_Host0.AppView.detectChanges (http://127.0.0.1:4200/main.bundle.js:56393:14)
serie.service.ts
import { Injectable, Input } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class SerieService {
url = "//api.tvmaze.com/search/shows?q=";
getSerie(id){
this.url = "http://api.tvmaze.com/shows/"+ id +"?embed=episodes";
var re = '';
return this._http.get(this.url).map(this.cleanSerieData);
}
private cleanSerieData(res: Response){
let body = res.json();
var tmp = [];
body._embedded.episodes.forEach(el => {
if(tmp[el.season-1] == undefined){
tmp[el.season-1] = [];
}
tmp[el.season-1].push(el);
});
var clean = {
id: body.id,
name: body.name,
rating: body.rating.average,
airday: body.schedule.days,
airtime: body.schedule.time,
status: body.status,
summary: body.summary,
episodes:tmp,
countSeasons: tmp.length,
countEpisodes: body._embedded.episodes.length
};
return clean;
}
constructor(private _http:Http) { }
}
Search.component.ts
import { Component, OnInit } from '@angular/core';
import { SerieService } from './../serie.service';
import { Router, ActivatedRoute, Params } from '@angular/router';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
srh = '';
shows = [];
tmp = [];
id = undefined;
theshow = {};
search(event:any){
this.srh = event.target.value;
this.serieService.getSeries(this.srh)
.subscribe(res => {
console.log(res);
this.shows = res;
})
}
constructor(
private serieService: SerieService,
private route: ActivatedRoute,
private router: Router
) { }
ngOnInit() {
this.id = this.route.snapshot.params['id'];
this.searchFunction();
}
searchFunction()
{
if(this.id == undefined)
{
console.log('search functie');
}else{
this.serieService.getSerie(this.id).subscribe(res => {
console.log(res);
this.theshow = res;
console.log(res.episodes[0])
});
}
}
}
编辑,添加代码。
最终我的想法是我可以点击第 2 季(按钮)并通过更改为(使用变量 ofc)来获取第 2 季的所有剧集
非常感谢您的回复。
Stefan 的回答很接近,但缺少更新后的关键信息 post。
异步获取确实意味着尚未定义 show 变量上的剧集 属性。
到目前为止,您构建的内容有三种可能的解决方案:
- 将显示变量的初始化从
theshow = {}
更改为theshow = {episodes: []}
。 - 在渲染之前检查剧集是否存在。守卫没有在我的 plunker 中工作,但是
<table *ngIf="theshow?.episodes"><tr *ngFor="let episode of theshow.episodes[0]">
正在工作(theshow?.episodes?[0]
似乎不是有效的语法)。 - 创建可以实例化为虚拟对象的适当对象
theshow: ShowInformation = new ShowInformation()
,其中您已经适当地定义了 ShowInformation class 并且它正确地将空变量构造为占位符。 - 使用此 QA 中的异步管道,但它需要更多返工以获得更好的长期解决方案:
这是一个硬连线的 plunker 示例(我没有费心去实现搜索、路由等):http://plnkr.co/edit/i0Vx6cLmPyNyavLCwCeY?p=preview
您可以像下面这样操作:
<tr *ngFor="let ep of theshow.episodes">
<td class="mailbox-name">{{ep[0].name}}</td>
<td class="mailbox-subject">{{ep[0].airdate}}</td>
<td class="mailbox-date">{{ep[0].airtime}}</td>
</tr>