Apa perbedaan antara keduanya dan apa kasus penggunaan untuk masing-masing?
The docs tidak persis membantu:
forRoot membuat modul yang berisi semua arahan, rute yang diberikan, dan layanan router itu sendiri.
forChild membuat modul yang berisi semua arahan dan rute yang diberikan, tetapi tidak menyertakan layanan router.
Dugaan samar saya adalah bahwa satu untuk modul 'utama' dan yang lainnya untuk modul yang diimpor (karena mereka sudah memiliki layanan yang tersedia dari modul utama), tetapi saya tidak dapat benar-benar memikirkan kasus penggunaan.
RouterService
untuk satu aplikasi Angular2.forRoot
akan menginisialisasi layanan itu dan mendaftarkannya ke DI bersama dengan beberapa konfigurasi rute, sementaraforChild
hanya akan mendaftarkan konfigurasi rute tambahan dan memberi tahu Angular2 untuk menggunakan kembaliRouterService
yangforRoot
telah dibuat.Jawaban:
Saya sangat menyarankan membaca artikel ini:
Modul dengan penyedia
Saat Anda mengimpor modul, Anda biasanya menggunakan referensi ke kelas modul:
Dengan cara ini semua penyedia yang terdaftar di modul
A
akan ditambahkan ke injektor akar dan tersedia untuk seluruh aplikasi.Tetapi ada cara lain untuk mendaftarkan modul dengan penyedia seperti ini:
Ini memiliki implikasi yang sama dengan yang sebelumnya.
Anda mungkin tahu bahwa modul yang dimuat lambat memiliki injektor sendiri. Jadi misalkan Anda ingin mendaftar
AService
agar tersedia untuk seluruh aplikasi, tetapi beberapaBService
hanya tersedia untuk modul yang dimuat lambat. Anda dapat memfaktorkan ulang modul Anda seperti ini:Sekarang
BService
hanya akan tersedia untuk modul pemuatan lambat anak danAService
akan tersedia untuk seluruh aplikasi.Anda dapat menulis ulang di atas sebagai modul yang diekspor seperti ini:
Bagaimana itu relevan dengan RouterModule?
Misalkan keduanya diakses menggunakan token yang sama:
Dengan konfigurasi terpisah ketika Anda meminta
token
dari modul yang dimuat lambat, Anda akan mendapatkanBService
seperti yang direncanakan.RouterModule menggunakan
ROUTES
token untuk mendapatkan semua rute khusus untuk sebuah modul. Karena ingin rute khusus untuk modul yang dimuat lambat tersedia di dalam modul ini (analog dengan BService kami), ia menggunakan konfigurasi berbeda untuk modul turunan yang dimuat lambat:sumber
forRoot
modul yang dimuat lambat akan membuat instance baru dari semua layanan global di injektor modul yang dimuat lambat. Ya, ini akan memberikan hasil yang tidak terduga. Baca juga artikel ini Menghindari kebingungan umum dengan modul di AngularSaya pikir jawabannya benar tetapi saya pikir ada sesuatu yang hilang.
Hal yang kurang adalah "mengapa dan apa yang dipecahkannya?".
Ok mari kita mulai.
Pertama mari kita sebutkan beberapa info:
Semua modul memiliki akses ke layanan root.
Jadi, bahkan modul yang dimuat lambat dapat menggunakan layanan yang disediakan di
app.module
.Apa yang akan terjadi jika modul yang dimuat lambat akan menyediakan layanan yang telah disediakan oleh modul aplikasi itu sendiri? akan ada 2 contoh.
Itu bukan masalah tapi terkadang memang begitu .
Bagaimana kita bisa mengatasinya? cukup jangan mengimpor modul dengan penyedia tersebut ke modul yang dimuat lambat.
Akhir dari cerita.
^ Ini hanya untuk menunjukkan bahwa modul yang dimuat lambat memiliki titik injeksi mereka sendiri (berbeda dengan modul yang tidak dimuat dengan lambat).
Tetapi apa yang terjadi ketika modul bersama (!) Telah dideklarasikan
providers
, dan modul itu diimpor oleh lazy danapp.module
? Sekali lagi, seperti yang kami katakan, dua contoh.Jadi bagaimana kita bisa menyelesaikan ini di modul POV bersama? Kami membutuhkan cara untuk tidak menggunakan
providers:[]
! Mengapa? karena keduanya akan diimpor secara otomatis ke penggunaan lazy dan app.module dan kami tidak menginginkannya karena kami melihat bahwa masing-masing akan memiliki instance yang berbeda.Nah, ternyata kita dapat mendeklarasikan modul bersama yang tidak akan dimiliki
providers:[]
, tetapi tetap akan menyediakan penyedia (maaf :))Bagaimana? Seperti ini :
Perhatikan, tidak ada penyedia.
Tapi
apa yang akan terjadi sekarang ketika app.module akan mengimpor modul bersama dengan POV layanan? TIDAK ADA.
apa yang akan terjadi sekarang ketika modul malas akan mengimpor modul bersama dengan POV layanan? TIDAK ADA.
Memasuki mekanisme Manual melalui konvensi:
Anda akan melihat bahwa penyedia di gambar memiliki
service1
danservice2
Ini memungkinkan kita untuk mengimpor
service2
modul yang dimuat lambat danservice1
untuk modul non-malas. ( batuk ... router .... batuk )BTW, tidak ada yang menghentikan Anda untuk menelepon
forRoot
dalam modul malas. tetapi Anda akan memiliki 2 instance karenaapp.module
harus melakukannya - jadi jangan lakukan itu di modul lazy.Juga - jika
app.module
panggilanforRoot
(dan tidak ada yang memanggilforchild
) - tidak apa-apa, tetapi injektor akar hanya akan melakukannyaservice1
. (tersedia untuk semua aplikasi)Jadi mengapa kita membutuhkannya? Aku akan mengatakan :
Itu dia.
Nah - itu tersembunyi dalam kalimat di atas ^
The konvensi (!!!) memungkinkan untuk menjadi tunggal - atau lebih tepatnya - jika Anda tidak akan mengikuti konvensi - Anda akan tidak mendapatkan tunggal.
Jadi jika Anda hanya memuat
forRoot
diapp.module
, maka Anda hanya mendapatkan satu contoh karena Anda hanya harus memanggilnyaforRoot
diapp.module
.BTW - pada titik ini Anda bisa melupakan
forChild
. modul yang dimuat malas seharusnya / tidak akan memanggilforRoot
- jadi Anda aman di POV tunggal.forRoot dan forChild bukanlah satu paket yang tidak dapat dipecahkan - hanya saja tidak ada gunanya memanggil Root yang jelas hanya akan dimuat
app.module
tanpa memberikan kemampuan untuk modul malas, memiliki layanan sendiri, tanpa membuat layanan baru-yang-seharusnya-ada. -singleton.Konvensi ini memberi Anda kemampuan bagus yang dipanggil
forChild
- untuk menggunakan "layanan hanya untuk modul yang dimuat lambat".Berikut ini demo Penyedia root menghasilkan angka positif, modul yang dimuat lambat menghasilkan angka negatif.
sumber
Dokumentasi dengan jelas menyatakan apa tujuan dari perbedaan ini di sini: https://angular.io/docs/ts/latest/guide/ngmodule.html#!#core-for-root
Setiap aplikasi memiliki tepat satu titik awal (root) tempat layanan perutean utama harus diinisialisasi
forRoot
, sedangkan rute untuk fitur "turunan" tertentu harus didaftarkan sebagai tambahanforChild
. Ini sangat berguna untuk submodul dan modul yang dimuat lambat yang tidak harus dimuat saat aplikasi dimulai, dan seperti yang dikatakan @Harry Ninh, mereka diberitahu untuk menggunakan kembali RouterService alih-alih pendaftaran layanan baru, yang dapat menyebabkan kesalahan waktu proses.sumber
Jika appRoutes berisi jalur ke berbagai fungsi di situs (admin crud, user crud, book crud) dan kami ingin memisahkannya, kami dapat melakukannya:
Dan untuk rute:
sumber