角度2 ngOnInit被调用两次有错误

时间:2016-10-11 19:47:53

标签: angular typescript

我在Angular 2中遇到了一个奇怪的错误。我有两个类似的组件,它们具有相似的模板和类似的服务。以下是它们如何工作的基础知识:

组件:

theData: any;

constructor(private _theService: TheService) {}

ngOnInit() {
    this._theService.getData()
        .subscribe(data => {
            this.theData = data;
        });
}

服务:

private _url = "http://url.net/api/Data";

constructor(private _http: Http) {
}

getData() {
    return this._http.get(this._url)
        .map(res => res.json());
}

返回一个对象数组,如:

[
    {name: "Name 1"},
    {name: "Name 2"}
]

,模板显示如下:

<div *ngFor="let item of theData">{{ item.name }}</div>

然后你可以点击一个项目,你被带到一个遵循上面相同策略的页面,除了service / api只返回一个对象而模板不使用* ngFor,因为只有一个项目到秀。

所以看起来像:

theItem = {name: "Name 1"} // what the service returns

<div>{{ theItem.name }}</div>

当显示所有项目时,一切都很好,但当我点击单个项目时,OnInit被调用两次,我在platform-b​​rowser.umd.js中出错,这在模板中确实是一个错误,因为它说的是无法读取name的属性undefined(即theItem)。

我通过将单个项目的模板更改为:

来解决了这个问题
<div>{{ theItem?.name }}</div>

起初我认为问题是模板在从服务加载数据之前呈现,因此添加?修复它。但是,在ngOnInit完成后,模板是否应该加载?我的问题是,为什么添加?可以解决此问题,即使我在加载所有项目时在第一个模板中不需要它?

感谢。

1 个答案:

答案 0 :(得分:4)

因为get是异步的,它实际上在加载数据之前就开始渲染模板。它将触发服务电话并且不会等待,它将继续处理。添加?可使其为undefined,然后在加载数据后进行适当渲染。