ngOnInit non viene chiamato quando la classe iniettabile è istanziata


198

Perché non viene ngOnInit()chiamato quando una Injectableclasse viene risolta?

Codice

import {Injectable, OnInit} from 'angular2/core';
import { RestApiService, RestRequest } from './rest-api.service';

@Injectable()
export class MovieDbService implements OnInit {

    constructor(private _movieDbRest: RestApiService){
        window.console.log('FROM constructor()');
    }

    ngOnInit() {
         window.console.log('FROM ngOnInit()');
    }

}

Uscita console

FROM constructor()

Risposte:


314

Ganci per il ciclo di vita , come il OnInit()lavoro con Direttive e Componenti. Non funzionano con altri tipi, come un servizio nel tuo caso. Da documenti:

Un componente ha un ciclo di vita gestito dalla stessa Angular. Angular lo crea, lo rende, crea e rende i suoi figli, lo controlla quando le sue proprietà associate ai dati cambiano e lo distruggono prima di rimuoverlo dal DOM.

Le istanze delle direttive e dei componenti hanno un ciclo di vita poiché Angular li crea, aggiorna e li distrugge.


38
Quindi semplicemente spostare la mia ngOnInitlogica nel costruttore per le Injectableclassi? Mi sono appena ricordato di aver letto che dovresti tenere qualsiasi logica fuori dal costruttore per qualsiasi motivo.
Levi Fuller,

48
@LeviFuller Sì, per i servizi è possibile eseguire l'inizializzazione nel costruttore o meglio creare il metodo init e chiamarlo dal costruttore (nel caso in cui sia necessario ripristinare un servizio in un secondo momento).
Sasxa,

9
Non esattamente, OnInit ha a che fare con l'associazione. Lo si utilizza quando si desidera attendere la risoluzione dei valori di input, poiché non sono disponibili nel costruttore. Il costruttore può essere chiamato più volte. Ad esempio, quando cambi percorso e carichi componenti diversi, questi vengono "costruiti" e distrutti ogni volta ...
Sasxa

5
Vale anche la pena notare qui che i Sevices possono essere istanziati più volte, a seconda di dove li includi negli providersarray. Se si desidera un servizio singleton, inserirlo nel modulo principale providerse se si desidera servizi per componente, aggiungerli direttamente al componente.
Askdesigners,

4
Questo non è del tutto errato, poiché @ SBD580 indica nella sua risposta, ngOnDestroyviene chiamato per i servizi iniettati
shusson,

48

Non conosco tutti gli hook del ciclo di vita, ma per quanto riguarda la distruzione, in ngOnDestroyrealtà vengono richiamati su Injectable quando il suo provider viene distrutto (ad esempio un Injectable fornito da un componente).

Dal docs :

Hook per il ciclo di vita che viene chiamato quando viene distrutta una direttiva, una pipe o un servizio .

Nel caso in cui qualcuno sia interessato alla distruzione, controlla questa domanda:


2
una tale vergogna ngOnInitnon si chiama :-( Volevo davvero fare un po 'di magia trasparente di inizializzazione ritardata. Se ngOnDestroyposso essere chiamato non vedo perché init non può
Simon_Weaver

2

Nota: questa risposta si applica solo ai componenti e alle direttive angolari, NON ai servizi.

Ho avuto lo stesso problema quando ngOnInit(e altri hook del ciclo di vita) non funzionavano per i miei componenti e la maggior parte delle ricerche mi ha portato qui.

Il problema è che stavo usando la sintassi della funzione freccia ( =>) in questo modo:

class MyComponent implements OnInit {
    // Bad: do not use arrow function
    public ngOnInit = () => {
        console.log("ngOnInit");
    }
}

Apparentemente ciò non funziona in Angolare 6. L'uso della sintassi della funzione non freccia risolve il problema:

class MyComponent implements OnInit {
    public ngOnInit() {
        console.log("ngOnInit");
    }
}

Le classi iniettabili sono Servizi, non Componenti. OP chiede un servizio. Sebbene la tua risposta possa essere corretta da un POV in lingua, non risponde a questa domanda. Dovresti eliminarlo.
Andrew Philips,

@AndrewPhilips mentre il mio caso d'uso è leggermente diverso dagli OP, una ricerca su Google di "ngOnInit non chiamato" porta le persone qui. Il mio obiettivo con questa risposta non è di aiutare l'OP, ma di aiutare qualsiasi degli altri 70.000+ spettatori che potrebbero avere problemi simili con ngOnInit.
AJ Richardson,

Giusto. Credo di aver visto domande e risposte in cui un autore chiede e poi risponde alla propria domanda. Come nuovo programmatore angolare, la tua risposta mi avrebbe confuso due settimane fa. Sia dal punto di vista SO che da quello GN, penso che la tua risposta sia degna della sua stessa domanda, quindi non cancellata ma "ricategorizzata". Chissà? Forse potrebbe raggiungere un pubblico ancora più ampio. Saluti.
Andrew Philips,

1
Ha senso: ho modificato la mia risposta per chiarire che non è per i servizi.
AJ Richardson,

0

Ho dovuto chiamare una funzione una volta inizializzato il mio dataService, invece, l'ho chiamata all'interno del costruttore, che ha funzionato per me.


0
import {Injectable, OnInit} from 'angular2/core';
import { RestApiService, RestRequest } from './rest-api.service';
import {Service} from "path/to/service/";

@Injectable()
export class MovieDbService implements OnInit {

userId:number=null;

constructor(private _movieDbRest: RestApiService,
            private instanceMyService : Service ){

   // do evreything like OnInit just on services

   this._movieDbRest.callAnyMethod();

   this.userId = this.instanceMyService.getUserId()


}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.