Angular2 - 插值对象是'undefined'但是console.log()有效

时间:2016-12-22 22:57:47

标签: angular

我正在研究一个非常简单的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]

2 个答案:

答案 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}}