2017-05-15 2 views
0

Also ging ich durch die Dokumentation auf der Angular Website, und ich baute die grundlegende "Heroes" App.Wie kann ich auf diese Variable zugreifen? this.hero

Ich habe versucht, auf den Variablenhelden der Eingabe zuzugreifen, da ich eine bestimmte Variable habe, die ich ausgeben möchte, aber ich bekomme Fehler.

Error: Uncaught (in promise): TypeError: this.hero is undefined 

Dieser Aufruf funktioniert in jedem anderen Verfahren, zum Beispiel ein Verfahren, das bei den Tasten Verwendung genannt wird, aber wenn ich versuche, es in ngOnInit() aufzurufen, es stürzt ab und gibt mir, dass Fehler.

Hier ist mein Code:

this.route.params.switchMap((params: Params) => this.heroService.getHero(+params['id'])).subscribe(hero => this.hero = hero); 
console.log(this.hero.background); 

wo Hintergrund ein Attribut des Helden ist.

Ich brauche keinen spezifischen Code - das war nur etwas, das nicht im Tutorial behandelt wurde und ich hätte gerne eine Richtung.

Ich habe viele Stunden damit verbracht, zu suchen, aber ich werde immer erfolglos bleiben - jetzt, bevor ich alle meine hört, kann jemand mir eine Führung geben?

Got für Code gefragt so ist es hier ist

import { Component, Input, OnInit } from '@angular/core'; 
import { ActivatedRoute, Params } from '@angular/router'; 
import { Location }     from '@angular/common'; 

import { HeroService } from './hero.service'; 
import { Hero } from './hero'; 

import 'rxjs/add/operator/switchMap'; 

let body = document.getElementsByTagName('body')[0]; 
@Component({ 
    selector: 'hero-detail', 
    templateUrl: './hero-detail.component.html', 
    styleUrls: [ './hero-detail.component.css' ] 
}) 


export class HeroDetailComponent implements OnInit { 
    @Input() hero: Hero; 
    constructor(
    private heroService: HeroService, 
    private route: ActivatedRoute, 
    private location: Location 
) { } 

    oldBody:string = body.style.backgroundImage; 

    ngOnInit(): void { 
    this.route.params.switchMap((params: Params) => this.heroService.getHero(+params['id'])).subscribe(hero => this.hero = hero); 

    console.log(this.hero.background); 
    } 

    ngOnDestroy() { 
     body.style.backgroundImage = this.oldBody; 
    } 

    goBack(): void { 
    this.location.back(); 
    } 

    updateBackground(): void { 
    body.style.backgroundImage = "url('"+this.hero.background+ "')"; 
    } 

    save(): void { 
    this.heroService.update(this.hero) 
    .then(() => this.goBack()); 
    } 
} 
+0

Folgen Sie Ihre Logik Schritt Schritt und stellen Sie sicher sein, dass die „this“ Schlüsselwort im Kontext ist, dass Sie denken es ist. – Bindrid

+0

@Bindrid Richtig, in meinen Variablen-Deklarationen habe ich '@Input() held: Hero;' also würde der Zugriff auf dieses "" Schlüsselwort verwendet werden, nicht wahr? Ich meine, es gibt keinen anderen Weg, den ich kenne - wenn ich normalen Helden ohne dieses Schlüsselwort verwende, gibt es mir einen Fehler, der mich auffordert, auf die Instanz zu verweisen. – seeocon

+0

Können Sie bitte etwas mehr Code zur Verfügung stellen? – Tamas

Antwort

0

Das Problem ist, dass Ihre console.log ausgeführt wird, bevor das beobachtbare Abonnement eine Chance hat zu feuern. Das Feld 'Held' ist nicht definiert, bis der Rückruf des Abonnements tatsächlich ausgeführt wird.

Sie sollten das Konsolenprotokoll in das Abonnement wie folgt bewegen:

this.route.params.switchMap((params: Params) => 
    this.heroService.getHero(+params['id']) 
).subscribe(hero => { 
    this.hero = hero; 
    console.log(this.hero.background); 
}); 
+0

Haha wow, das war schnell, danke für die Rückmeldung. Ich denke, jeder muss irgendwo anfangen. Um Ihre Änderungen besser zu verstehen; Was ich tat war streng definiert die Variable, aber die ** ngOnInit ** hat die Variable noch nicht tatsächlich initialisiert, durch die Schaffung eines Blockes stellt es sicher, dass die Variable initialisiert wird? – seeocon

+0

Wenn Sie einen Block erstellen (geschweifte Klammern hinzufügen), ändert sich nichts, außer dass Sie mehrere Anweisungen schreiben können. (Als Konvention verwende ich immer geschweifte Klammern in Subscribe Callbacks, auch wenn es nur eine Aussage ist. Ich denke, es ist klarer.) Wie auch immer, der Code in der 'subscribe' Funktion wird asynchron ausgeführt (nach getHero() abgeschlossen). Aber Code außerhalb des subscribe Callbacks, wo Sie die console.log zuvor hatten, wird synchron ausgeführt. – dbandstra

0

bieten Sie tatsächlich einen Helden als Input() wenn Sie die Komponente verwenden ?? Wenn nicht, sollten Sie den Code nur lesen:

export class HeroDetailComponent implements OnInit { 
    public hero: Hero 
// rest of your code 
+0

Ich war für das Beispiel, aber ich hörte auf, es zu benutzen, als ich anfing, an meiner Mini-App zu arbeiten. Ich habe versucht, es vorher öffentlich zu machen und es hat immer noch nicht funktioniert. : \ – seeocon

+0

Was passiert, wenn Sie eine sehr einfache/grundlegende Komponente entwickeln?So etwas wie die Exportklasse TestComponent implementiert OnInit {public message; ngOnInit() this.message = 'Hallo'; } Das sollte einfach funktionieren. – Tamas

0

Da Sie hero als Input Ihrer Komponente definieren, und Sie können wie unten, um es direkt von Ihrem Parent gesetzt:

<hero-detail [hero]="selectedHero"></hero-detail> // here selectedHero is what you selected from ParenComponent 

und nach Der Fehler (this.hero is undefined) Sie konfrontiert sind, haben Sie nicht die oben genannte Sache, so dass die @Input() hero ist immer noch undefiniert, bis Sie Daten von this.heroService.getHero zurückbekommen haben.

So einfach müssen Sie die console.log auf die subscribe von this.heroService.getHero verschieben, weil es ein asynchroner Anruf ist.

Verwandte Themen