ngOnInit tidak dipanggil ketika kelas Injectable di-Instantiated


197

Mengapa tidak ngOnInit()dipanggil ketika Injectablekelas diselesaikan?

Kode

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()');
    }

}

Output Konsol

FROM constructor()

Jawaban:


312

Kait siklus hidup , seperti OnInit()bekerja dengan Arahan dan Komponen. Mereka tidak bekerja dengan tipe lain, seperti layanan dalam kasus Anda. Dari dokumen:

Komponen memiliki siklus hidup yang dikelola oleh Angular sendiri. Angular menciptakannya, menjadikannya, menciptakan dan menjadikan anak-anaknya, memeriksanya ketika sifat-sifatnya yang terikat data berubah dan menghancurkannya sebelum memindahkannya dari DOM.

Petunjuk dan komponen komponen memiliki siklus hidup sebagai Angular membuat, memperbarui, dan menghancurkannya.


38
Jadi cukup gerakkan ngOnInitlogika saya ke konstruktor untuk Injectablekelas? Saya baru ingat membaca bahwa Anda harus menjaga logika dari konstruktor untuk alasan apa pun.
Levi Fuller

48
@LeviFuller Ya, untuk layanan Anda dapat melakukan inisialisasi di konstruktor, atau lebih baik membuat metode init dan memanggilnya dari konstruktor (jika Anda perlu mengatur ulang layanan nanti).
Sasxa

9
Tidak juga, OnInit berkaitan dengan pengikatan. Anda menggunakannya ketika Anda ingin menunggu nilai input diselesaikan, karena mereka tidak tersedia di konstruktor. Konstruktor dapat dipanggil beberapa kali. Misalnya, ketika Anda mengubah rute dan memuat komponen yang berbeda, komponen tersebut akan "dikonstruksi" dan dihancurkan setiap kali ...
Sasxa

5
Penting juga dicatat di sini bahwa Sevices dapat dipakai beberapa kali, tergantung di mana Anda memasukkannya ke dalam providersarray. Jika Anda menginginkan layanan tunggal, letakkan di modul utama Anda providers, dan jika Anda ingin layanan per-komponen, tambahkan langsung ke komponen tersebut.
Askdesigners

4
Ini tidak sepenuhnya salah, seperti @ SBD580 poin dalam jawabannya, ngOnDestroydipanggil untuk layanan yang disuntikkan
shusson

48

Saya tidak tahu tentang semua kait siklus hidup, tetapi untuk penghancuran, ngOnDestroybenar-benar dipanggil pada Injectable ketika penyedianya dihancurkan (misalnya Injectable yang disediakan oleh komponen).

Dari docs :

Kait siklus hidup yang disebut ketika direktif, pipa atau layanan dihancurkan.

Kalau-kalau ada orang yang tertarik pada perusakan, periksa pertanyaan ini :


2
rasa malu seperti ngOnInititu tidak disebut :-( Saya benar-benar ingin melakukan beberapa sihir inisialisasi tertunda transparan. Jika ngOnDestroybisa disebut saya tidak melihat mengapa init tidak bisa
Simon_Weaver

2

Catatan: jawaban ini hanya berlaku untuk komponen dan arahan Angular, BUKAN layanan.

Saya memiliki masalah yang sama ketika ngOnInit(dan kait siklus hidup lainnya) tidak menembakkan komponen saya, dan sebagian besar pencarian membawa saya ke sini.

Masalahnya adalah saya menggunakan sintaks fungsi panah ( =>) seperti ini:

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

Tampaknya itu tidak berfungsi di Angular 6. Menggunakan sintaks fungsi non-panah memperbaiki masalah:

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

Kelas injeksi adalah Layanan, bukan Komponen. OP bertanya tentang Layanan. Meskipun jawaban Anda mungkin benar dari POV bahasa, itu tidak menjawab pertanyaan ini. Anda harus menghapusnya.
Andrew Philips

@AndrewPhilips sementara kasus penggunaan saya sedikit berbeda dari OP, pencarian google untuk "ngOnInit tidak disebut" memimpin orang di sini. Tujuan saya dengan jawaban ini bukan untuk membantu OP, tetapi untuk membantu lebih dari 70.000 penonton lainnya yang mungkin memiliki masalah serupa ngOnInit.
AJ Richardson

Cukup adil. Saya percaya saya telah melihat SO T&J di mana penulis bertanya dan kemudian menjawab pertanyaan mereka sendiri. Sebagai programmer Angular baru, jawaban Anda akan membingungkan saya dua minggu lalu. Baik dari perspektif SO dan NG, saya pikir jawaban Anda layak untuk Pertanyaannya sendiri, jadi tidak dihapus tapi "dikategorikan ulang". Siapa tahu? Mungkin bisa menjangkau khalayak yang lebih luas. Bersulang.
Andrew Philips

1
Masuk akal - saya mengedit jawaban saya untuk menjelaskan bahwa ini bukan untuk layanan.
AJ Richardson

0

Saya harus memanggil fungsi begitu layanan data saya diinisialisasi, sebagai gantinya, saya menyebutnya di dalam konstruktor, yang berfungsi untuk saya.


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()


}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.