我正在研究一个非常简单的Angular2应用程序,但是我遇到了一个问题,浏览器将插值组件对象评估为undefined
,但我能够console.log(this)
进入组件并查看值,虽然“刚刚评估了以下值”,但请注意。
对于上下文,我已经使用Angular2命令行工具启动了我的应用程序,但我正在松散地遵循Angular2的“英雄之旅”教程(它使用压缩的快速入门包来组装基本文件)...
导致此问题的模板是person-detail.component.html
,其中我非常简单:
<div>Welcome, {{ person.name }}</div>
以下是关联的person-detail.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import 'rxjs/add/operator/switchMap';
import { PersonService } from './person.service';
import { Person } from './person';
@Component({
selector: 'person-details',
templateUrl: './person-details.component.html'
})
export class PersonDetailsComponent implements OnInit {
@Input() person: Person;
constructor(
private personService: PersonService,
private route: ActivatedRoute,
private location: Location
) {};
ngOnInit(): void {
this.route.params
.switchMap((params: Params) => this.personService.getPerson(+params['id']))
.subscribe(person => this.person = person);
console.log(this) //THIS LOGS THE COMPLETE OBJECT AS I WANT IT, BUT WITH THE 'Value below...' NOTE
};
}
和person.service.ts
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import 'rxjs/add/operator/map';
import { Observable } from "rxjs/Observable";
import { Person } from './person';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class PersonService {
private apiUrl = 'http://localhost:4000/api/';
constructor(private http: Http) {
console.log('Service ready...');
}
getPeople(): Promise<Person[]> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http
.get(this.apiUrl + 'people', options)
.toPromise()
.then(response => response.json().data as Person[])
}
getPerson(id: number): Promise<Person> {
return this.getPeople()
.then(people => people.find(person => person.id === id));
}
}
但是当我导航到该页面时,我收到错误inline template:0:5 caused by: Cannot read property 'name' of undefined
,尽管console.log()
返回的数据看起来不错。
从概念上讲,我理解发生了什么......页面的部分是在对象完全形成之前呈现的。但是我很困惑,因为据我所知,我把事情放在一起的方式与“英雄之旅”教程完全相同,该教程工作得很好 - 除了我用命令行启动我的项目这一事实工具(以稍微不同的方式构建项目)并且我使用一些标题选项等连接到我自己的API ...
如何设置它以使页面的部分在尝试渲染之前等待对象完全形成?
注意 - 如果我尝试插入{{ person }}
,浏览器会显示[object Object]
答案 0 :(得分:9)
console.log
给你一个错误的印象,因为当你尝试在模板中访问它时,person
仍然是undefined
,尽管你没有时间欣赏如果来自服务器的响应足够快,则在控制台中进行更改。所以你需要使用safe navigation operator。
<div>Welcome, {{ person?.name }}</div>
答案 1 :(得分:0)
在某些情况下,您可能需要考虑使用typescript getters。它们将允许您为您的属性设置默认值。
<person-details [personInput]="details"></person-details>
这样称呼:
<div>Welcome, {{ person.name }}</div>
然后在您的PersonDetailsComponent中,无需任何更改即可使用它:
{{1}}