2016-10-11 21 views
3

角度2で奇妙なエラーが発生しました。同様のテンプレートと同様のサービスを持つ2つの同様のコンポーネントがあります。ここでは、彼らがどのように動作するかの基本です:角度2 ngOnInitがエラーで2回呼び出されました

コンポーネント:

theData: any; 

constructor(private _theService: TheService) {} 

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

サービス:

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

とテンプレート:これは次のように、オブジェクトの配列を返します

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

constructor(private _http: Http) { 
} 

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

次のように表示されます:

次に、service/apiが1つのオブジェクトだけを返し、テンプレートが* ngForを使用しないことを除いて、上記と同じ戦略に従うページに移動するアイテムをクリックすることができます表示する項目。

ようなので、それが見えます:すべてがすべての項目を表示するときに素晴らしい作品が、私は、個々の項目にクリックしたとき、のOnInitが2回呼び出され、私は、プラットフォームにbrowser.umd.jsでエラーが出ます

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

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

テンプレートの実際には、nameundefined(これはtheItemです)を読み取ることができないと言われています。

私は、個々の項目のテンプレートを変更することで、この問題を解決:私はそう?はそれを修正追加、問題は、データがサービスからロードされていた前に、テンプレートがレンダリングされたことだと思った最初は

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

。しかし、ngOnInitの終了後にテンプレートが読み込まれるべきではありませんか?私の質問は、?を追加すると、なぜすべてのアイテムを読み込むときに最初のテンプレートにその必要がないのに、この問題が修正されたのですか?

ありがとうございました。

答えて

4

getは非同期であるため、実際にはデータがロードされる前にテンプレートのレンダリングが開始されます。それはサービスコールを起動し、待機しません、処理を続行します。 ?を追加すると、undefinedになり、データがロードされると適切にレンダリングされます。

+0

あなたが最初のシナリオで動作する唯一の理由は、サービスがデータを十分に速く返すためで、テンプレートはまだレンダリングされていないからです。 – user5021816

+0

または '* ngFor'はそれが未定義であることを扱いますが、オブジェクトを直接参照することはできません。私は正直に分かりませんが、私は実際にそのシナリオを掘り下げたことはありません –

+0

ええ、私はそれが同様に扱われたかどうか疑問に思っていました。もし私が何か他のものを見つけたら、私は報告します。ありがとうございました! – user5021816