Saya mengalami sedikit kesulitan memahami Dependency Injection di Angular. Jadi pertanyaan saya adalah, adakah yang bisa menjelaskan "jenis" mana, seperti Pengendali, Pabrik, Penyedia, dll yang dapat kita suntikkan ke orang lain, termasuk contoh lain dari "jenis" yang sama?
Apa yang sebenarnya saya cari adalah tabel ini diisi dengan y / n. Untuk sel dengan baris / kolom yang sama, itu berarti menyuntikkan nilai dari satu "jenis" ke yang lain dengan "jenis" yang sama
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
| Can we inject? | Constant | Controller | Directive | Factory | Filter | Provider | Service | Value |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
| Constant | | | | | | | | |
| Controller | | | | | | | | |
| Directive | | | | | | | | |
| Factory | | | | | | | | |
| Filter | | | | | | | | |
| Provider | | | | | | | | |
| Service | | | | | | | | |
| Value | | | | | | | | |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
angularjs
dependency-injection
pengguna1527166
sumber
sumber
Jawaban:
Alih-alih itu hanya mengisi tabel dengan "ya" dan "tidak" tanpa penjelasan, saya akan membahas sedikit lebih detail.
[Catatan, ditambahkan setelah selesai: ini akhirnya ... sedikit lebih lama dari yang saya harapkan. Ada tl; dr di bagian bawah, tapi saya harap ini membuktikan informasi.]
[Jawaban ini juga telah ditambahkan ke wiki AngularJS: Understanding Dependency Injection ]
Penyedia (
$provide
)The
$provide
layanan bertanggung jawab untuk memberitahu sudut cara membuat hal-hal yang disuntikkan baru; hal-hal ini disebut layanan . Layanan ditentukan oleh hal-hal yang disebut penyedia , yang merupakan apa yang Anda buat saat Anda gunakan$provide
. Menentukan penyedia dilakukan melaluiprovider
metode pada$provide
layanan, dan Anda dapat memperoleh$provide
layanan dengan memintanya untuk disuntikkan ke fungsi aplikasiconfig
. Contohnya mungkin seperti ini:Di sini kami telah menetapkan penyedia baru untuk layanan yang disebut
greeting
; kita bisa menyuntikkan variabel yang dinamaigreeting
ke fungsi injeksi apa saja (seperti pengendali, lebih lanjut tentang itu nanti) dan Angular akan memanggil fungsi penyedia$get
untuk mengembalikan contoh layanan yang baru. Dalam hal ini, hal yang akan disuntikkan adalah fungsi yang mengambilname
parameter dan menyimpanalert
pesan berdasarkan namanya. Kami mungkin menggunakannya seperti ini:Nah, inilah triknya.
factory
,,service
danvalue
semuanya hanya jalan pintas untuk menentukan berbagai bagian penyedia - yaitu, mereka menyediakan sarana untuk menentukan penyedia tanpa harus mengetikkan semua hal itu. Misalnya, Anda dapat menulis penyedia yang sama persis seperti ini:Ini penting untuk dipahami, jadi saya akan ulangi: di bawah tenda, AngularJS memanggil kode yang sama persis yang kita tulis di atas (
$provide.provider
versi) untuk kita. Secara harfiah, 100% tidak ada perbedaan dalam dua versi.value
bekerja dengan cara yang sama - jika apa pun yang kita akan kembali dari$get
fungsi kita (aliasfactory
fungsi kita ) selalu persis sama, kita dapat menulis lebih sedikit menggunakan kodevalue
. Misalnya, karena kami selalu mengembalikan fungsi yang sama untukgreeting
layanan kami , kami juga dapat menggunakannyavalue
untuk mendefinisikannya:Sekali lagi, ini 100% identik dengan dua metode lain yang kami gunakan untuk mendefinisikan fungsi ini - ini hanya cara untuk menghemat pengetikan.
Sekarang Anda mungkin memperhatikan hal menjengkelkan
app.config(function($provide) { ... })
yang telah saya gunakan. Karena mendefinisikan penyedia baru (melalui salah satu metode yang diberikan di atas) sangat umum, AngularJS memaparkan$provider
metode langsung pada objek modul, untuk menyimpan lebih banyak mengetik:Ini semua melakukan hal yang sama dengan versi yang lebih verbose yang
app.config(...)
kami gunakan sebelumnya.Injeksi yang saya lewati sejauh ini adalah
constant
. Untuk saat ini, cukup mudah untuk mengatakan bahwa itu berfungsi seperti ituvalue
. Kita akan melihat ada satu perbedaan nanti.Untuk meninjau , semua bagian kode ini melakukan hal yang persis sama:
Injector (
$injector
)Injektor bertanggung jawab untuk benar-benar membuat contoh layanan kami menggunakan kode yang kami berikan melalui
$provide
(tidak ada permainan kata pun). Setiap kali Anda menulis fungsi yang mengambil argumen yang disuntikkan, Anda melihat injektor sedang bekerja. Setiap aplikasi AngularJS memiliki satu$injector
yang akan dibuat ketika aplikasi pertama kali dimulai; Anda bisa memperolehnya dengan menyuntikkan$injector
ke fungsi injeksi apa pun (ya,$injector
tahu cara menyuntikkan sendiri!)Setelah memilikinya
$injector
, Anda bisa mendapatkan instance dari layanan yang ditentukan dengan memanggilnyaget
dengan nama layanan. Sebagai contoh,Injektor juga bertanggung jawab untuk menyuntikkan layanan ke dalam fungsi; misalnya, Anda dapat secara ajaib menyuntikkan layanan ke fungsi apa pun yang Anda miliki menggunakan metode injektor
invoke
;Perlu dicatat bahwa injektor hanya akan membuat instance layanan satu kali . Kemudian cache apa pun penyedia kembali dengan nama layanan; kali berikutnya Anda meminta layanan, Anda akan benar-benar mendapatkan objek yang sama persis.
Jadi, untuk menjawab pertanyaan Anda, Anda bisa menyuntikkan layanan ke fungsi apa pun yang dipanggil
$injector.invoke
. Ini termasuk$get
metode penyedia (aliasfactory
fungsi definisi)Karena
constant
s danvalue
s selalu mengembalikan nilai statis, mereka tidak dipanggil melalui injektor, dan dengan demikian Anda tidak dapat menyuntikkan mereka dengan apa pun.Mengkonfigurasi Penyedia
Anda mungkin bertanya-tanya mengapa ada orang yang repot-repot untuk mendirikan sebuah penyedia penuh dengan
provide
metode jikafactory
,value
, dll jauh lebih mudah. Jawabannya adalah bahwa penyedia mengizinkan banyak konfigurasi. Kami telah menyebutkan bahwa ketika Anda membuat layanan melalui penyedia (atau salah satu pintasan yang diberikan Angular), Anda membuat penyedia baru yang menentukan bagaimana layanan itu dibangun. Yang tidak saya sebutkan adalah bahwa penyedia ini dapat disuntikkan keconfig
bagian aplikasi Anda sehingga Anda dapat berinteraksi dengan mereka!Pertama, Angular menjalankan aplikasi Anda dalam dua fase - fase
config
danrun
. Theconfig
fase, seperti yang kita lihat, adalah di mana Anda dapat mengatur penyedia apapun yang diperlukan. Ini juga tempat arahan, pengontrol, filter, dan sejenisnya diatur. Therun
fase, seperti yang Anda duga, adalah di mana sudut sebenarnya mengkompilasi DOM dan dijalankan aplikasi Anda.Anda dapat menambahkan kode tambahan untuk dijalankan dalam fase ini dengan
myMod.config
danmyMod.run
fungsi - masing-masing mengambil fungsi untuk dijalankan selama fase tertentu. Seperti yang kita lihat di bagian pertama, fungsi-fungsi ini dapat disuntikkan - kami menyuntikkan layanan bawaan dalam$provide
sampel kode pertama kami. Namun, yang perlu dicatat adalah bahwa selamaconfig
fase ini, hanya penyedia yang dapat disuntikkan (dengan pengecualian layanan dalamAUTO
modul -$provide
dan$injector
).Misalnya, yang berikut ini tidak diizinkan :
Apa yang Anda lakukan memiliki akses ke apapun penyedia layanan yang telah Anda buat:
Ada satu pengecualian penting:
constant
s, karena mereka tidak dapat diubah, diizinkan untuk disuntikkan di dalamconfig
blok (ini adalah bagaimana mereka berbeda darivalue
s). Mereka diakses dengan nama mereka sendiri (tidakProvider
perlu suffix).Setiap kali Anda menentukan penyedia untuk layanan, penyedia itu dinamai
serviceProvider
, di manaservice
adalah nama layanan. Sekarang kita dapat menggunakan kekuatan penyedia melakukan beberapa hal yang lebih rumit!Sekarang kami memiliki fungsi pada penyedia kami yang disebut
setText
dapat kami gunakan untuk menyesuaikanalert
; kita bisa mendapatkan akses ke penyedia ini dalam satuconfig
blok untuk memanggil metode ini dan menyesuaikan layanan. Ketika kami akhirnya menjalankan aplikasi kami, kami dapat mengambilgreeting
layanan, dan mencobanya untuk melihat bahwa kustomisasi kami mulai berlaku.Karena ini adalah contoh yang lebih kompleks, inilah demonstrasi yang berfungsi: http://jsfiddle.net/BinaryMuse/9GjYg/
Pengendali (
$controller
)Fungsi-fungsi pengontrol dapat disuntikkan ke dalam, tetapi pengontrol itu sendiri tidak dapat disuntikkan ke hal-hal lain. Itu karena pengendali tidak dibuat melalui penyedia. Sebaliknya, ada layanan Angular built-in yang disebut
$controller
yang bertanggung jawab untuk mengatur pengendali Anda. Saat Anda meneleponmyMod.controller(...)
, Anda sebenarnya sedang mengakses penyedia layanan ini , seperti di bagian terakhir.Misalnya, saat Anda mendefinisikan pengontrol seperti ini:
Apa yang sebenarnya Anda lakukan adalah ini:
Kemudian, ketika Angular perlu membuat turunan dari pengontrol Anda, ia menggunakan
$controller
layanan (yang pada gilirannya menggunakan$injector
untuk memanggil fungsi pengontrol Anda sehingga ketergantungannya juga disuntikkan).Filter dan Arahan
filter
dandirective
bekerja dengan cara yang persis sama seperticontroller
;filter
menggunakan layanan yang disebut$filter
dan penyedianya$filterProvider
, sementaradirective
menggunakan layanan yang disebut$compile
dan penyedianya$compileProvider
. Beberapa tautan:Seperti contoh lainnya,
myMod.filter
danmyMod.directive
merupakan pintasan untuk mengonfigurasi layanan ini.Jadi, untuk meringkas, fungsi apa pun yang dipanggil
$injector.invoke
dapat disuntikkan . Ini termasuk, dari bagan Anda (tetapi tidak terbatas pada):$get
(saat mendefinisikan provider sebagai objek)Penyedia menciptakan layanan baru yang dapat disuntikkan ke dalam berbagai hal . Ini termasuk:
Yang mengatakan, layanan built-in seperti
$controller
dan$filter
dapat disuntikkan, dan Anda dapat menggunakan layanan tersebut untuk mendapatkan filter dan pengendali baru yang Anda tetapkan dengan metode-metode tersebut (meskipun hal-hal yang Anda tentukan sendiri tidak dapat disuntikkan ke dalam berbagai hal).Selain itu, fungsi apa pun yang disuntikkan injektor dapat disuntikkan dengan layanan yang disediakan penyedia apa pun - tidak ada batasan (selain dari
config
danrun
perbedaan yang tercantum di sini).sumber
Poin yang dibuat BinaryMuse dalam jawabannya yang menakjubkan tentang penyedia, pabrik, dan layanan semuanya menjadi hal yang sama sangat penting.
Di bawah ini adalah gambar yang menurut saya dapat menggambarkan maksudnya secara visual:
(sumber: simplygoodcode.com )
sumber
Jawaban yang bagus dari Michelle. Saya hanya ingin menunjukkan bahwa arahan dapat disuntikkan. Jika Anda memiliki arahan bernama
myThing
, Anda dapat menyuntikkannya denganmyThingDirective
: Ini adalah contoh yang dibuat-buat .Contoh di atas tidak terlalu praktis, namun kemampuan untuk menyuntikkan arahan berguna ketika Anda ingin menghias arahan itu .
sumber