我正在尝试创建一个用户详细信息页面,您可以在其中获得有关所选用户的更多信息。 当您从列表中单击用户名时,它会成功导航到用户详细信息页面,但会抛出此错误:
Unhandled Promise rejection: Error in src/person-details.component.html:3:25 caused by: Cannot read property 'id' of undefined
这是一个插件: http://embed.plnkr.co/cUEIag77etv95ZFJY3iN/
以下是代码:
人-list.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { IPerson } from './person';
import { AppService } from './app.service';
@Component({
selector: 'my-list',
templateUrl: 'src/person-list.component.html'
})
export class PersonListComponent implements OnInit {
_persons: IPerson[];
selectedPerson: IPerson;
constructor(
private _appService: AppService,
private router: Router) { }
ngOnInit(): void {
this._appService.getPersons()
.subscribe(
_persons => this._persons = _persons); // set our local _persons array equal to the IPerson[] data which arrive from our data stream
}
goToDetails(person: IPerson): void {
this.router.navigate(['/user', person.id])
}
}
人-list.component.html
<div class="container-fluid">
<div class='table-responsive'>
<table class='table'>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let person of _persons" (click)="goToDetails(person)" class="row">
<td>{{person.id}}</td>
<td>{{person.name}}</td>
</tr>
</tbody>
</table>
</div>
</div>
人-details.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import { AppService } from './app.service';
import { IPerson } from './person';
@Component({
selector: 'my-details',
templateUrl: 'src/person-details.component.html'
})
export class PersonDetailsComponent implements OnInit {
constructor(
private _appService: AppService,
private route: ActivatedRoute,
private location: Location
) { }
ngOnInit(): void {
this.route.params.forEach((params: Params) => { // delivers our array of route parameters.
let id = +params['id']; // The person id is a number. Route parameters are always strings. So we convert the route parameter value to a number with the JavaScript (+) operator.
this._appService.getPerson(id)
.map(person => this.person = person);
});
}
// navigates backward one step in the browser's history stack using the Location service we injected
goBack(): void {
this.location.back();
}
}
人-details.component.html
<div class="container">
<h3>Person Details</h3>
<div class="col-md-12">
<div><span>Id:</span> {{person.id}}</div>
<div><span>Name:</span> {{person.name}}</div>
<div><span>Description:</span> {{person.description}}</div>
</div>
<button (click)="goBack()">Back</button>
</div>
app.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http'; // required for getting persons from JSON file
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'; // required by the .map method
import { IPerson } from './person';
@Injectable() export class AppService {
private _personUrl = 'src/persons.json';
constructor(private _http: Http) { } // required to Inject Http as a dependency. Creates a private _http variable and assigns the injected service instance to that variable
getPersons(): Observable<IPerson[]> {
return this._http.get(this._personUrl)
.map((response: Response) => <IPerson[]>response.json().personData); // we let the compiler know that the array contains items of type 'IPerson' and return the 'personData' object from the json file as an array
}
// filters the person list from getPersons by id
getPerson(id: number): Observable<IPerson> {
return this.getPersons()
.map(persons => persons.find(person => person.id === id));
}
}
答案 0 :(得分:2)
初始化PersonDetailsComponent时,field person为null,thar会导致模板绑定出错。您可以使用field?.subfield
替换模板绑定以解决该问题。
<div class="container">
<h3>Person Details</h3>
<div class="col-md-12">
<div><span>Id:</span> {{person?.id}}</div>
<div><span>Name:</span> {{person?.name}}</div>
<div><span>Description:</span> {{person?.description}}</div>
</div>
<button (click)="goBack()">Back</button>
</div>
我已将plunker编辑为包含这些更改的版本。我还需要编辑PersonDetailsComponent以订阅getPerson()observable。