Saya telah melihat angular.factory () dan angular.service () digunakan untuk mendeklarasikan layanan; Namun, saya tidak dapat menemukan angular.service
di mana pun dalam dokumentasi resmi.
Apa perbedaan antara kedua metode ini?
Yang harus digunakan untuk apa (dengan asumsi mereka melakukan hal yang berbeda)?
angularjs
angular-services
Jacobs
sumber
sumber
Jawaban:
Saya mengalami kesulitan membungkus kepala saya di sekitar konsep ini sampai saya menempatkannya pada diri saya seperti ini:
Layanan : fungsi yang Anda tulis akan baru :
Pabrik : fungsi (konstruktor) yang Anda tulis akan dipanggil :
Apa yang Anda lakukan dengan itu terserah Anda, tetapi ada beberapa pola yang berguna ...
Seperti menulis fungsi layanan untuk mengekspos API publik:
Atau menggunakan fungsi pabrik untuk mengekspos API publik:
Atau menggunakan fungsi pabrik untuk mengembalikan konstruktor:
Yang mana yang akan digunakan? ...
Anda dapat mencapai hal yang sama dengan keduanya. Namun, dalam beberapa kasus, pabrik memberi Anda sedikit lebih banyak fleksibilitas untuk membuat suntikan dengan sintaksis yang lebih sederhana. Itu karena sementara myInjectedService harus selalu menjadi objek, myInjectedFactory dapat berupa objek, referensi fungsi, atau nilai apa pun. Misalnya, jika Anda menulis layanan untuk membuat konstruktor (seperti pada contoh terakhir di atas), itu harus dibuat seperti ini:
yang bisa dibilang kurang diinginkan dari ini:
(Tapi Anda harus waspada tentang penggunaan pola jenis ini di tempat pertama karena objek yang baru di controller Anda menciptakan dependensi sulit dilacak yang sulit untuk dipermainkan untuk pengujian. Lebih baik memiliki layanan mengelola koleksi objek untuk Anda daripada menggunakan dengan
new()
cerdik.)Satu hal lagi, mereka semua lajang ...
Juga perlu diingat bahwa dalam kedua kasus, sudut membantu Anda mengelola tunggal. Terlepas dari di mana atau berapa kali Anda menyuntikkan layanan atau fungsi Anda, Anda akan mendapatkan referensi yang sama ke objek atau fungsi yang sama. (Dengan pengecualian ketika pabrik hanya mengembalikan nilai seperti angka atau string. Dalam hal ini, Anda akan selalu mendapatkan nilai yang sama, tetapi bukan referensi.)
sumber
new fn()
, jadi mereka harus mengembalikan instance.Sederhananya ..
sumber
Inilah perbedaan utamanya:
Jasa
Sintaksis:
module.service( 'serviceName', function );
Hasil: Saat mendeklarasikan serviceName sebagai argumen yang dapat disuntikkan, Anda akan diberikan instance fungsi yang diteruskan ke
module.service
.Penggunaan: Dapat bermanfaat untuk berbagi fungsi utilitas yang berguna untuk dipanggil hanya dengan menambahkan
( )
referensi fungsi yang disuntikkan. Bisa juga dijalankan denganinjectedArg.call( this )
atau serupa.Pabrik
Sintaksis:
module.factory( 'factoryName', function );
Hasil: Saat mendeklarasikan factoryName sebagai argumen injeksi, Anda akan diberikan nilai yang dikembalikan dengan menggunakan referensi fungsi yang diteruskan ke
module.factory
.Penggunaan: Dapat bermanfaat untuk mengembalikan 'kelas' yang kemudian dapat digunakan untuk membuat instance.
Berikut ini adalah contoh menggunakan layanan dan pabrik . Baca lebih lanjut tentang Layanan AngularJS vs Pabrik .
Anda juga dapat memeriksa dokumentasi AngularJS dan pertanyaan serupa tentang stackoverflow yang bingung tentang layanan vs pabrik .
sumber
$providers
waktu.this.myFunc = function(){}
di layanan Anda (menyelamatkan Anda dari menulis kode untuk membuat objek seperti yang harus Anda lakukan dengan pabrik) ).TL; DR
1) Saat Anda menggunakan Pabrik, Anda membuat objek, menambahkan properti ke sana, lalu mengembalikan objek yang sama. Ketika Anda melewati pabrik ini ke controller Anda, properti-properti pada objek sekarang akan tersedia di controller melalui pabrik Anda.
2) Saat Anda menggunakan Layanan , Angular membuat instance di belakang layar dengan kata kunci 'baru'. Karena itu, Anda akan menambahkan properti ke 'ini' dan layanan akan mengembalikan 'ini'. Ketika Anda melewati layanan ke controller Anda, properti-properti di 'ini' sekarang akan tersedia pada controller itu melalui layanan Anda.
Non TL; DR
1) Pabrik
Pabrik adalah cara paling populer untuk membuat dan mengonfigurasi layanan. Benar-benar tidak lebih dari apa yang dikatakan TL; DR. Anda cukup membuat objek, menambahkan properti ke sana, lalu mengembalikan objek yang sama. Kemudian ketika Anda melewati pabrik ke controller Anda, properti-properti pada objek sekarang akan tersedia di controller melalui pabrik Anda. Contoh yang lebih luas ada di bawah ini.
Sekarang properti apa pun yang kita lampirkan ke 'layanan' akan tersedia untuk kita ketika kita melewati 'myFactory' ke controller kita.
Sekarang mari kita tambahkan beberapa variabel 'pribadi' ke fungsi panggilan balik kita. Ini tidak akan dapat diakses langsung dari controller, tetapi kami akhirnya akan menyiapkan beberapa metode pengambil / penyetel pada 'layanan' untuk dapat mengubah variabel 'pribadi' ini ketika diperlukan.
Di sini Anda akan melihat kami tidak melampirkan variabel / fungsi itu ke 'layanan'. Kami hanya membuatnya untuk menggunakan atau memodifikasinya nanti.
Sekarang, ketika variabel pembantu dan fungsi dan fungsi kami sudah ada, mari kita tambahkan beberapa properti ke objek 'layanan'. Apa pun yang kita pakai pada 'layanan' kita akan dapat langsung menggunakan pengontrol mana pun yang kita lewati 'myFactory'.
Kita akan membuat metode setArtist dan getArtist yang hanya mengembalikan atau mengatur artis. Kami juga akan membuat metode yang akan memanggil iTunes API dengan URL yang kami buat. Metode ini akan mengembalikan janji yang akan dipenuhi setelah data telah kembali dari iTunes API. Jika Anda belum memiliki banyak pengalaman menggunakan janji-janji di Angular, saya sangat merekomendasikan melakukan penyelaman mendalam pada mereka.
Di bawah setArtist menerima artis dan memungkinkan Anda untuk mengatur artis. getArtist mengembalikan artist callItunes panggilan pertama makeUrl () untuk membangun URL yang akan kami gunakan dengan permintaan $ http kami. Kemudian ia membuat objek janji, membuat permintaan $ http dengan url akhir kami, lalu karena $ http mengembalikan janji, kami dapat memanggil .success atau .error setelah permintaan kami. Kami kemudian menyelesaikan janji kami dengan data iTunes, atau kami menolaknya dengan pesan yang mengatakan 'Ada kesalahan'.
Sekarang pabrik kami selesai. Kami sekarang dapat menyuntikkan 'myFactory' ke dalam pengontrol apa pun dan kami kemudian dapat memanggil metode kami yang kami lampirkan ke objek layanan kami (setArtist, getArtist, dan callItunes).
Pada controller di atas kami menyuntikkan layanan 'myFactory'. Kami kemudian mengatur properti pada objek $ scope kami yang berasal dari data dari 'myFactory'. Satu-satunya kode rumit di atas adalah jika Anda belum pernah berurusan dengan janji sebelumnya. Karena callItunes mengembalikan janji, kita dapat menggunakan metode .then () dan hanya menetapkan $ scope.data.artistData setelah janji kita dipenuhi dengan data iTunes. Anda akan melihat pengontrol kami sangat 'tipis'. Semua logika dan data persisten kami terletak di layanan kami, bukan di controller kami.
2) Layanan
Mungkin hal terbesar yang perlu diketahui ketika berhadapan dengan menciptakan Layanan adalah bahwa itu dipakai dengan kata kunci 'baru'. Bagi Anda guru JavaScript ini harus memberi Anda petunjuk besar tentang sifat kode. Bagi Anda yang memiliki latar belakang terbatas dalam JavaScript atau bagi mereka yang tidak terlalu mengenal apa kata kunci 'baru' sebenarnya, mari kita tinjau beberapa dasar-dasar JavaScript yang pada akhirnya akan membantu kita dalam memahami sifat dari suatu Layanan.
Untuk benar-benar melihat perubahan yang terjadi ketika Anda menjalankan fungsi dengan kata kunci 'baru', mari kita membuat fungsi dan memohonnya dengan kata kunci 'baru', lalu mari kita tunjukkan apa yang dilakukan penerjemah ketika melihat kata kunci 'baru'. Hasil akhirnya akan sama.
Pertama mari kita buat konstruktor kita.
Ini adalah fungsi konstruktor JavaScript yang khas. Sekarang setiap kali kita memanggil fungsi Person menggunakan kata kunci 'baru', 'ini' akan terikat ke objek yang baru dibuat.
Sekarang mari kita tambahkan metode ke prototipe Person kita sehingga akan tersedia pada setiap instance 'kelas' Person kita.
Sekarang, karena kita meletakkan fungsi sayName pada prototipe, setiap instance dari Person akan dapat memanggil fungsi sayName untuk mengingatkan nama instance itu.
Sekarang kita memiliki fungsi konstruktor Person kita dan fungsi sayName kita pada prototipe, mari kita benar-benar membuat instance Person kemudian memanggil fungsi sayName.
Jadi, bersama-sama kode untuk membuat konstruktor Person, menambahkan fungsi ke prototipe itu, membuat contoh Person, dan kemudian memanggil fungsi pada prototipe terlihat seperti ini.
Sekarang mari kita lihat apa yang sebenarnya terjadi ketika Anda menggunakan kata kunci 'baru' dalam JavaScript. Hal pertama yang harus Anda perhatikan adalah bahwa setelah menggunakan 'baru' dalam contoh kami, kami dapat memanggil metode (sayName) di 'tyler' seolah-olah itu adalah objek - itu karena itu. Jadi pertama-tama, kita tahu bahwa konstruktor Person kita mengembalikan objek, apakah kita dapat melihatnya dalam kode atau tidak. Kedua, kita tahu bahwa karena fungsi sayName kita terletak pada prototipe dan tidak langsung pada contoh Person, objek yang dikembalikan fungsi Person harus didelegasikan ke prototipe pada pencarian gagal. Dalam istilah yang lebih sederhana, ketika kita memanggil tyler.sayName () interpreter mengatakan “OK, aku akan melihat objek 'tyler' yang baru saja kita buat, cari fungsi sayName, lalu panggil saja. Tunggu sebentar, saya tidak melihatnya di sini - yang saya lihat hanyalah nama dan umur, izinkan saya memeriksa prototipe. Yup, sepertinya ada di prototipe, biar saya sebut saja. ”.
Di bawah ini adalah kode untuk cara Anda berpikir tentang apa yang sebenarnya dilakukan kata kunci 'baru' dalam JavaScript. Ini pada dasarnya adalah contoh kode paragraf di atas. Saya telah menempatkan 'tampilan penerjemah' atau cara penerjemah melihat kode di dalam catatan.
Sekarang memiliki pengetahuan tentang apa yang sebenarnya dilakukan kata kunci 'baru' dalam JavaScript, membuat Layanan di Angular harus lebih mudah dipahami.
Hal terbesar untuk dipahami saat membuat Layanan adalah mengetahui bahwa Layanan dipakai dengan kata kunci 'baru'. Menggabungkan pengetahuan itu dengan contoh-contoh kami di atas, Anda sekarang harus mengakui bahwa Anda akan melampirkan properti dan metode Anda langsung ke 'ini' yang kemudian akan dikembalikan dari Layanan itu sendiri. Mari kita lihat ini dalam aksi.
Tidak seperti apa yang awalnya kami lakukan dengan contoh Pabrik, kita tidak perlu membuat objek lalu mengembalikan objek itu karena, seperti yang disebutkan berkali-kali sebelumnya, kita menggunakan kata kunci 'baru' sehingga penerjemah akan membuat objek itu, minta didelegasikan kepada itu prototipe, lalu kembalikan untuk kita tanpa kita harus melakukan pekerjaan.
Hal pertama yang pertama, mari kita buat fungsi 'pribadi' dan penolong kami. Ini seharusnya terlihat sangat akrab karena kami melakukan hal yang persis sama dengan pabrik kami. Saya tidak akan menjelaskan apa yang dilakukan setiap baris di sini karena saya melakukannya di contoh pabrik, jika Anda bingung, baca kembali contoh pabrik.
Sekarang, kami akan melampirkan semua metode kami yang akan tersedia di controller kami untuk 'ini'.
Sekarang sama seperti di pabrik kami, setArtist, getArtist, dan callItunes akan tersedia di mana pun controller kita lewati myService. Inilah pengendali myService (yang hampir persis sama dengan pengontrol pabrik kami).
Seperti yang saya sebutkan sebelumnya, begitu Anda benar-benar memahami apa yang 'baru' lakukan, Layanan hampir identik dengan pabrik di Angular.
sumber
Petunjuk ada dalam nama
Layanan dan pabrik mirip satu sama lain. Keduanya akan menghasilkan objek tunggal yang dapat disuntikkan ke objek lain, dan sering digunakan secara bergantian.
Mereka dimaksudkan untuk digunakan secara semantik untuk menerapkan pola desain yang berbeda.
Layanan adalah untuk menerapkan pola layanan
Pola layanan adalah pola di mana aplikasi Anda dipecah menjadi unit fungsional yang konsisten secara logis. Contohnya mungkin pengakses API, atau serangkaian logika bisnis.
Hal ini sangat penting dalam Angular karena model Angular biasanya hanya objek JSON yang ditarik dari server, jadi kami membutuhkan tempat untuk meletakkan logika bisnis kami.
Berikut adalah layanan Github misalnya. Ia tahu cara berbicara dengan Github. Ia tahu tentang url dan metode. Kita bisa menyuntikkannya ke controller, dan itu akan menghasilkan dan mengembalikan janji.
Pabrik menerapkan pola pabrik
Pabrik, di sisi lain dimaksudkan untuk menerapkan pola pabrik. Pola pabrik di mana kita menggunakan fungsi pabrik untuk menghasilkan objek. Biasanya kita dapat menggunakan ini untuk membangun model. Berikut adalah pabrik yang mengembalikan konstruktor Penulis:
Kami akan menggunakan ini seperti ini:
Perhatikan bahwa pabrik juga mengembalikan lajang.
Pabrik dapat mengembalikan konstruktor
Karena pabrik hanya mengembalikan objek, itu dapat mengembalikan semua jenis objek yang Anda suka, termasuk fungsi konstruktor, seperti yang kita lihat di atas.
Pabrik mengembalikan objek; layanan baru
Perbedaan teknis lainnya adalah dalam hal layanan dan pabrik disusun. Fungsi layanan akan dikabarkan baru untuk menghasilkan objek. Fungsi pabrik akan dipanggil dan akan mengembalikan objek.
Ini berarti bahwa dalam suatu layanan, kami menambahkan "ini" yang, dalam konteks konstruktor, akan menunjuk ke objek yang sedang dibangun.
Untuk menggambarkan hal ini, berikut adalah objek sederhana yang sama dibuat menggunakan layanan dan pabrik:
sumber
Author
parameter injektor seharusnyaPerson
.Semua jawaban di sini tampaknya ada di sekitar layanan dan pabrik, dan itu sah karena itulah yang ditanyakan. Tapi itu juga penting untuk diingat bahwa ada beberapa orang lain termasuk
provider()
,value()
, danconstant()
.Kunci untuk diingat adalah bahwa masing-masing adalah kasus khusus dari yang lain. Setiap kasing khusus memungkinkan Anda melakukan hal yang sama dengan kode lebih sedikit. Masing-masing juga memiliki beberapa batasan tambahan.
Untuk memutuskan kapan harus menggunakan yang baru saja Anda lihat mana yang memungkinkan Anda melakukan apa yang Anda inginkan dalam kode yang lebih sedikit. Berikut adalah gambar yang menggambarkan betapa miripnya mereka:
Untuk rincian langkah demi langkah lengkap dan referensi cepat kapan harus menggunakan masing-masing Anda dapat mengunjungi posting blog tempat saya mendapatkan gambar ini dari:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
sumber
app.factory ('fn', fn) vs. app.service ('fn', fn)
Konstruksi
Dengan pabrik, Angular akan memanggil fungsi untuk mendapatkan hasilnya. Ini adalah hasil yang di-cache dan disuntikkan.
Dengan layanan, Angular akan memanggil fungsi konstruktor dengan memanggil yang baru . Fungsi yang dibangun di-cache dan disuntikkan.
Penerapan
Pabrik biasanya mengembalikan objek literal karena nilai kembali adalah apa yang disuntikkan ke pengontrol, menjalankan blok, arahan, dll
Fungsi layanan biasanya tidak mengembalikan apa pun. Sebagai gantinya, mereka melakukan inisialisasi dan mengekspos fungsi. Fungsi juga dapat merujuk 'ini' karena dibangun menggunakan 'baru'.
Kesimpulan
Dalam hal menggunakan pabrik atau layanan, keduanya sangat mirip. Mereka disuntikkan ke controller, arahan, run block, dll, dan digunakan dalam kode klien dengan cara yang hampir sama. Keduanya juga lajang - yang berarti contoh yang sama dibagi antara semua tempat di mana layanan / pabrik disuntikkan.
Jadi mana yang harus Anda pilih? Salah satunya - mereka sangat mirip sehingga perbedaannya sepele. Jika Anda memilih salah satu dari yang lain, perhatikan saja cara pembuatannya, sehingga Anda dapat menerapkannya dengan benar.
sumber
Saya telah menghabiskan beberapa waktu untuk mencari tahu perbedaannya.
Dan saya pikir fungsi pabrik menggunakan pola modul dan fungsi layanan menggunakan pola konstruktor skrip java standar.
sumber
Pola pabrik lebih fleksibel karena dapat mengembalikan fungsi dan nilai serta objek.
Tidak ada banyak titik dalam pola layanan IMHO, karena semua yang dilakukannya dapat dengan mudah dilakukan dengan pabrik. Pengecualian mungkin:
Bisa dibilang, pola layanan adalah cara yang sedikit lebih baik untuk membuat objek baru dari sudut pandang sintaksis, tetapi juga lebih mahal untuk instantiate. Yang lain telah mengindikasikan bahwa sudut menggunakan "baru" untuk membuat layanan, tetapi ini tidak sepenuhnya benar - tidak dapat melakukan itu karena setiap konstruktor layanan memiliki jumlah parameter yang berbeda. Apa yang sebenarnya dilakukan angular adalah menggunakan pola pabrik secara internal untuk membungkus fungsi konstruktor Anda. Kemudian ia melakukan beberapa pokery jiggery yang pandai untuk mensimulasikan operator "baru" javascript, memanggil konstruktor Anda dengan sejumlah variabel argumen yang dapat diinjeksi - tetapi Anda dapat meninggalkan langkah ini jika Anda hanya menggunakan pola pabrik secara langsung, sehingga sangat sedikit meningkatkan efisiensi Anda kode.
sumber
function MyFactory(dep1) { var $$foo = 'bar', factory = {}; Object.defineProperties(factory.prototype, { foo: { value: $$foo } }); return factory; }
function MyService(dep1) { var $$foo = 'bar'; Object.defineProperties(MyService.prototype, { foo: { value: $$foo } }); }
Sementara MyFactory dan MyService menggunakan prototipe, MyFactory masih membutuhkan kinerja karena harus membuat objek yang sedang dikembalikan. Dalam kedua contoh, mereka memiliki privat, tetapi di MyService relatif tidak ada perbedaan kinerja.MyFactory(someArgument)
(mis$http()
). Yang tidak mungkin dengan layanan seperti Anda akan referensi konstruktor:MyService(someArgument)
.