Die @ Input-Eigenschaft ist in onInit von Angular 2 undefiniert

73

Es wird versucht, den @InputWert der Komponente in constructoroder abzurufen ngOnInit. Aber es kommt wie undefinedimmer.

Ich habe den Heldenplunker mit aktualisiert console.log, um das Problem zu zeigen (Beta-Winkel). http://plnkr.co/edit/dseNM7OTFi1VNG2Z4Oj5?p=preview

export class HeroDetailComponent implements OnInit {
  constructor(){
    console.log('hero', this.hero)
  }
  public hero: Hero;
  
  ngOnInit() {
    console.log('hero', this.hero)
  }
}

Was mache ich hier falsch?

eesdil
quelle
Hmm, ich habe nicht bemerkt, dass wir in dem Beispiel nicht sofort den Helden auswählen ... Ich war froh, dass es auch im Plunker nicht funktioniert :) Ich habe es im Plunker überprüft und es funktioniert gut. In meinem Code funktioniert es jedoch nicht, aber es wird initialisiert ... Entschuldigung für den falschen Plunker. Ich werde die Antwort akzeptieren, aber sie löst mein Problem nicht.
Eesdil
1
Das Problem war also, dass ich die camelCase-Eigenschaft "inputProperty" in @Input eingefügt habe ... anstelle von "input-property" ... seltsamerweise nicht realisiert .. jedoch ist die API-Dokumentation so geschrieben.
Eesdil

Antworten:

111

Der Grund, warum Sie undefiniert werden, ngOnInitist, dass Sie an dem Punkt, an dem die Komponente initialisiert wird, noch kein HeroObjekt übergeben haben

<my-hero-detail [hero]="selectedHero"></my-hero-detail>

Zu diesem Zeitpunkt selectedHerohat Ihr Wert keinen Wert AppComponentund ruft erst auf, wenn das Klickereignis in der Liste die onSelectMethode aufruft

Bearbeiten: Tut mir leid, dass ich kein Update angeboten habe. Wenn Sie fügen Sie ein ngIfzumy-hero-detail

<my-hero-detail *ngIf="selectedHero" [hero]="selectedHero"></my-hero-detail>

Sie sollten die Initialisierung der my-hero-detailKomponente verzögern und die Konsolenausgabe sehen. Dies wird nicht jedoch wieder ausgegeben , wenn die ausgewählten Helden ändert.

Zyzle
quelle
3
Löse mein Problem, also danke. Denken Sie über den Tellerrand hinaus, vielleicht entdecken Sie etwas Neues
materliu
1
genial. Das habe ich gebraucht.
Michael Henderson
Hervorragende Lösung. Vielen Dank, Kumpel! :)
Objektmanipulator
45

Dies liegt daran, dass die Helden asynchron geladen werden. Wenn die Ansicht also anfänglich gerendert wird, ist der ausgewählte Held undefiniert. Nachdem eine Auswahl getroffen wurde, wird der Held mit einem definierten Wert in die Detailansicht übergeben.

Sie sehen im Grunde nur den onInit-Aufruf basierend auf dem ursprünglichen Wert (undefiniert).

Wenn Sie möchten, dass nach jeder Auswahl etwas Ähnliches ausgeführt wird, können Sie es folgendermaßen ändern:

export class HeroDetailComponent implements AfterViewChecked {
  constructor(){
    console.log('hero', this.hero)
  }
  public hero: Hero;

  ngAfterViewChecked() {
    console.log('hero', this.hero)
  }
}
TGH
quelle
Ja, das sollte es.
Amr ElAdawy
mit angle5. Fehler: ExpressionChangedAfterItHasBeenCheckedError: Der Ausdruck wurde geändert, nachdem er überprüft wurde. Vorheriger Wert: 'undefiniert'. Aktueller Wert: '[Objekt Objekt]'.
Faiz Mohamed Haneef
@FaizMohamedHaneef, das passiert, wenn Sie einen Wert in dieser Funktion ändern. Da Angular bereits alle Variablen auf Änderungen überprüft hat, erhalten Sie eine Warnung, wenn Sie einen Wert anschließend im Debug-Modus ändern (nicht in der Produktion, da Angular nicht wie beim Debug erneut überprüft wird). Wenn Sie einen Wert wirklich ändern müssen und sicher sind, dass Sie ihn korrekt verarbeiten, schließen Sie ihn in ein Timeout ein.
Agash Thamo.
20

Ich habe das gleiche Verhalten festgestellt, als ich den Wert der Eingabeeigenschaft in nicht definiert habe ngOnInit. Die Aussage *ngIf="selectedHero"im HTML-Code hat mich nicht zufrieden gestellt. Darüber hinaus war die Verwendung der AntwortAfterViewChecked von @ THG keine gute Lösung für mich, da sie regelmäßig aufgerufen wird und auch die Warnung auslöst, ExpressionChangedAfterItHasBeenCheckedErrorwenn ich eine Variable ändern möchte (ich wollte keine Problemumgehung verwenden setTimeout). Dies ist meine Lösung für diese Art von Problem:

export class MyComponent implements OnChanges {
    @Input() myVariable: any;

    ngOnChanges(changes: SimpleChanges) {
        if (changes['myVariable']) {
            let variableChange = changes['myVariable'];
            //do something with variableChange.currentValue
        }
    }
}

Ich hoffe es hilft später jemandem.

Barabas
quelle
Die if-Anweisung und die Variable in Klammern funktionierten in meinem Fall nicht, stattdessen habe ich einfach nach einer anderen Bedingung gesucht. Aber es hat funktioniert !! Vielen Dank
13.
es funktioniert richtig. Ich weiß nicht, warum er das nicht genehmigt hat.
Rupesh
0

In der ngOninit-Methode verwenden,

ngOnInit() {
    if(this.hero) 
        console.log('hero', this.hero);
}
Shubham Chandra
quelle
Kann jemand erklären, warum dies abgelehnt wurde? Dieser Fehler wurde in meinem Unit-Test behoben.
Matt123
1
Die Frage war, den Fehler nicht zu überspringen, sondern einen Weg zu finden, um den Fehler zu beheben
Anil8753