2016-01-16 13 views
18

私のアプリでは奇妙なエラーが発生しています。オブジェクトから{{thing.title}}をプリントアウトすることになったが、それはコンソールでエラーを示しています:角2:TypeError:l_thing0はAppComponent @ 4:44の[{{thing.title}}で未定義です

EXCEPTION: TypeError: l_thing0 is undefined in [{{thing.title}} in [email protected]:44] 

私はl_thing0がどこから来ているか分かりません。ページに{{thing}}と表示しようとすると、[object Object]と表示されます。 JSON.stringify(this.thing)showObj()関数を参照)にしようとすると、文字列化されたオブジェクトが正しく表示されます。しかし、{{thing.title}}のような属性にアクセスしようとすると、l_thing0が定義されていないというエラーが出ます。

import {Component, OnInit} from 'angular2/core'; 
import {Thing} from './thing'; 
import {ThingService} from './thing.service'; 
import {SubThingComponent} from "./subthing.component"; 

@Component({ 
    selector: 'thing-app', 
    template: ` 
     <div class="container"> 
      <div class="row"> 
       <div class="col-md-12"> 
        <h1>{{thing.title}} <a href="#" (click)="showObj()" class="btn btn-default">Show Stringified Obj</a></h1> 
        <subthing></subthing> 
       </div> 
      </div> 
     </div> 
    `, 
    styles:[` 

    `], 
    directives: [SubThingComponent], 
    providers: [ThingService] 
}) 

export class AppComponent implements OnInit { 

    constructor(private _thingService: ThingService) { } 

    public thing: Thing; 

    showObj() { 
     // This correctly shows the stringified object 
     alert(JSON.stringify(this.thing)); 
    } 

    getThing() { 
     this._thingService.getThing().then(thing => this.thing = thing); 
     // This correctly logs the object 
     setTimeout(() => {console.log('thing', this.thing)}, 5000); 
    } 

    ngOnInit() { 
     this.getThing(); 
    } 
} 

任意のアイデア:ここ

はapp.component.tsありますか?

+1

この '{{thing?.title}}'はエラーをなくしますか? – Langley

+0

はい、ありがとうございます。私はちょうどそれを考え出した。 (7時間後:/) – Josh

+1

np、その演算子に慣れないようにしてください。よりよい解決策を投稿しました。 – Langley

答えて

40

thingは、最初にページをロードするときに、未定義のままで、後で非同期で実際の値に設定されるため、プロパティにアクセスしようとすると例外がスローされます。 ?エルビス演算子はnullcheckへのショートカットです:

{{thing?.title}}

しかし、あなたのような何かを追加することにより、実際のオブジェクトを持ってまでも、すべてのコンポーネントをレンダリングしようとしないのが最善のアイデアよりパフォーマンス:

<h1 *ngIf="thing">

を容器に入れる。

+0

だから、 '?'の代わりに '* ngIf'を使わなければならないという意味ですか? –

+1

このソリューションは機能しますが、値がロードされるときにどのようにDOMジガーが発生するのを避けることができますか?タグに "Loading"のようなテキストを入力し、値が読み込まれるとスワップアウトされるような、エレガントな方法はありますか? – code4cause

+0

申し訳ありません私は今まであなたのメッセージを見たことがありません。これは完全に独立しています。データが非同期的にロードされている場合、ヌルチェックに関係なく発生します。 これは大丈夫ですが、取得したデータを読み込んで表示するデザイナーもいます。個人的には、私はこのちらつきが嫌い、私は情報が準備ができたら、ページ全体を読み込むことを好みます。私がこれを避けるために見つけた最良の方法は、ui-routerのようなルータの解決機能です。登録されたすべての解決策によってモデルがロードされるまで、コンポーネントは起動しません。 – Langley

0

isFinishedからfalseに新しい変数を設定してから、サーバーまたは非同期関数からデータを取得し、データを受信した後にtrueに設定することもできます。次にisFinished変数を*ngIfに入れて、サーバー/機能プロセスが完了しているかどうかを確認します。

0

私はパーティーに遅れて来ますが、これは角度5を使用している人に役立つかもしれないと考えました。 エルヴィスのオペレーターは* ngForループでは動作しませんが、* ngifではうまく動作しません。だから私の問題は、この問題に対処するコードです。

<div *ngIf = "fullObject?.objProperty"> 
     <h1>{{fullObject.objProperty1}}</h1> 
     <div *ngFor = "let o of fullObject.objPropertyArray"> 
      <h3>{{o._subheader}}</h3> 
      <p> 
       {{o._subtext}} 
      </p> 
     </div> 
    </div> 
</div> 
関連する問題