Saya menemukan bahwa semua istilah Angular mengintimidasi untuk pemula. Kami mulai dengan lembar contekan ini yang sedikit lebih mudah dipahami oleh programmer kami sambil mempelajari Angular demisx.github.io/angularjs/2014/09/14/… . Semoga ini bisa membantu tim Anda juga.
demisx
7
Menurut pendapat saya, cara terbaik untuk memahami perbedaannya adalah dengan menggunakan dokumentasi Angular sendiri: docs.angularjs.org/guide/providers dijelaskan dengan sangat baik dan menggunakan contoh khusus untuk membantu Anda memahaminya.
Rafael Merlin
3
@Blaise Terima kasih! Per komentar saya dalam posting ini, saya sengaja meninggalkannya, karena 99% kasus penggunaan dari pengalaman saya dapat ditangani dengan sukses service.factory. Tidak ingin memperumit masalah ini lebih lanjut.
Dari milis AngularJS saya mendapat utas luar biasa yang menjelaskan layanan vs pabrik vs penyedia dan penggunaan injeksi mereka. Kompilasi jawaban:
Jasa
Sintaks: module.service( 'serviceName', function );
Hasil: Saat mendeklarasikan serviceName sebagai argumen yang dapat diinjeksi, Anda akan diberikan instance dari fungsi tersebut. Dengan kata lainnew FunctionYouPassedToService() .
Pabrik
Sintaks: module.factory( 'factoryName', function );
Hasil: Ketika mendeklarasikan factoryName sebagai argumen injeksi, Anda akan diberikan nilai yang dikembalikan dengan memohon referensi fungsi yang diteruskan ke module.factory .
Penyedia
Sintaks: module.provider( 'providerName', function );
Hasil: Saat mendeklarasikan providerName sebagai argumen yang dapat diinjeksi, Anda akan diberikan(new ProviderFunction()).$get() . Fungsi konstruktor adalah instantiated sebelum metode $ get dipanggil - ProviderFunctionadalah referensi fungsi yang diteruskan ke module.provider.
Penyedia memiliki keuntungan bahwa mereka dapat dikonfigurasi selama fase konfigurasi modul.
Dalam edit 611 saya menambahkan penggunaan konstanta dan nilai sudut. Untuk menunjukkan perbedaan yang lain sudah ditunjukkan. jsbin.com/ohamub/611/edit
Contoh ini bisa luar biasa jika menggunakan contoh praktis yang jelas. Saya tersesat mencoba mencari tahu apa gunanya toEqualdan greeter.Greetapa. Mengapa tidak menggunakan sesuatu yang sedikit lebih nyata dan bisa dihubungkan?
Kyle Pennell
5
Menggunakan fungsi expect () adalah pilihan yang buruk untuk menjelaskan sesuatu. Gunakan kode dunia nyata lain kali.
Contoh "Hello world" dengan factory/ service/ provider:
var myApp = angular.module('myApp',[]);//service style, probably the simplest one
myApp.service('helloWorldFromService',function(){this.sayHello =function(){return"Hello, World!";};});//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory',function(){return{
sayHello:function(){return"Hello, World!";}};});//provider style, full blown, configurable version
myApp.provider('helloWorld',function(){this.name ='Default';this.$get =function(){var name =this.name;return{
sayHello:function(){return"Hello, "+ name +"!";}}};this.setName =function(name){this.name = name;};});//hey, we can configure a provider!
myApp.config(function(helloWorldProvider){
helloWorldProvider.setName('World');});functionMyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService){
$scope.hellos =[
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];}
Tidak thismengubah konteks dalam $getfungsi? - Anda tidak lagi merujuk ke penyedia instantiated dalam fungsi itu.
Nate-Wilkins
12
@Nate: thissebenarnya tidak mengubah konteks, karena apa yang dipanggil adalah new Provider()$ get (), di mana Providerfungsi diteruskan app.provider. Maksudnya dikatakan $get()dipanggil sebagai metode pada konstruksi Provider, jadi thisakan merujuk Providerseperti contoh yang disarankan.
Brandon
1
@Brandon Ohh ok itu bagus kalau begitu. Sekilas membingungkan - terima kasih atas klarifikasi!
Nate-Wilkins
3
Mengapa saya dapatkan Unknown provider: helloWorldProvider <- helloWorldketika menjalankan ini secara lokal? Mengomentari itu, kesalahan yang sama untuk 2 contoh lainnya. Apakah ada konfigurasi penyedia tersembunyi? (Angular 1.0.8) - Ditemukan: stackoverflow.com/questions/12339272/…
Antoine
4
Adalah alasan mengapa @Antoine mendapatkan kesalahan "Tidak diketahui: helloWorldProvider" karena dalam kode .config Anda, Anda menggunakan 'helloWorldProvider', tetapi ketika Anda menentukan penyedia di myApp.provider ('helloWorld', function ()), Anda menggunakan 'Halo Dunia'? Dengan kata lain, dalam kode konfigurasi Anda, bagaimana sudut tahu Anda merujuk ke penyedia helloWorld? Terima kasih
jmtoung
645
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 , AngularJS 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.
3) Penyedia adalah satu-satunya layanan yang dapat Anda gunakan untuk fungsi .config () Anda. Gunakan penyedia ketika Anda ingin memberikan konfigurasi modul-lebar untuk objek layanan Anda sebelum membuatnya tersedia.
app.controller(‘myProvider’,function($scope, myProvider){
$scope.artist = myProvider.getArtist();
$scope.data.thingFromConfig = myProvider.thingOnConfig;});
app.provider(‘myProvider’,function(){//Only the next two lines are available in the app.config()this._artist =‘’;this.thingFromConfig =‘’;this.$get =function(){var that =this;return{
getArtist:function(){return that._artist;},
thingOnConfig: that.thingFromConfig
}}});
app.config(function(myProviderProvider){
myProviderProvider.thingFromConfig =‘This was setin config’;});
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.
app.factory(‘myFactory’,function(){var service ={};return service;});
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.
baseUrl adalah URL dasar yang dibutuhkan oleh iTunes API
_artist adalah artis yang ingin kita cari
_finalUrl adalah URL final dan sepenuhnya dibangun yang kami akan membuat panggilan ke iTunes
makeUrl adalah fungsi yang akan membuat dan mengembalikan URL ramah iTunes kami.
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' dapat langsung digunakan di dalam pengontrol mana pun kita melewatkan '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 AngularJS, saya sangat merekomendasikan melakukan penyelaman mendalam pada mereka.
Di bawah setArtist menerima artis dan memungkinkan Anda untuk mengatur artis. getArtist mengembalikan artis. callItunes first calls 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 dengan 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' (Ini adalah praktik pengkodean yang baik). 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.
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.
Person.prototype.sayName =function(){
alert(‘My name is‘+this.name);}
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.
var tyler =newPerson(‘Tyler’,23);
tyler.sayName();//alerts ‘My name is Tyler’
Jadi secara keseluruhan kode untuk membuat konstruktor Person, menambahkan fungsi ke prototipe itu, membuat contoh Person, dan kemudian memanggil fungsi pada prototipe terlihat seperti ini.
varPerson=function(name, age){this.name = name;this.age = age;}Person.prototype.sayName =function(){
alert(‘My name is‘+this.name);}var tyler =newPerson(‘Tyler’,23);
tyler.sayName();//alerts ‘My name is Tyler’
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.
varPerson=function(name, age){//The below line creates an object(obj) that will delegate to the person’s prototype on failed lookups.//var obj = Object.create(Person.prototype);//The line directly below this sets ‘this’ to the newly created object//this = obj;this.name = name;this.age = age;//return this;}
Sekarang memiliki pengetahuan tentang apa kata kunci 'baru' sebenarnya dalam JavaScript, membuat Layanan di AngularJS harus lebih mudah dimengerti.
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 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, setelah Anda benar-benar memahami apa yang 'baru' lakukan, Layanan hampir identik dengan pabrik di AngularJS.
3) Penyedia
Hal terbesar yang harus diingat tentang Penyedia adalah mereka satu-satunya layanan yang dapat Anda masuki ke bagian app.config dari aplikasi Anda. Ini sangat penting jika Anda perlu mengubah sebagian dari objek layanan Anda sebelum tersedia di tempat lain di aplikasi Anda. Meskipun sangat mirip dengan Layanan / Pabrik, ada beberapa perbedaan yang akan kita bahas.
Pertama, kami mengatur Penyedia kami dengan cara yang sama seperti yang kami lakukan dengan Layanan dan Pabrik kami. Variabel di bawah ini adalah fungsi 'pribadi' dan penolong kami.
app.provider('myProvider',function(){var baseUrl ='https://itunes.apple.com/search?term=';var _artist ='';var _finalUrl ='';//Going to set this property on the config function below.this.thingFromConfig =‘’;var makeUrl =function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist +'&callback=JSON_CALLBACK'return _finalUrl;}}
* Lagi-lagi jika ada bagian dari kode di atas yang membingungkan, periksa bagian Pabrik di mana saya menjelaskan apa yang dilakukannya lebih detail.
Anda dapat menganggap Penyedia memiliki tiga bagian. Bagian pertama adalah variabel / fungsi 'pribadi' yang akan dimodifikasi / ditetapkan nanti (ditampilkan di atas). Bagian kedua adalah variabel / fungsi yang akan tersedia di fungsi app.config Anda dan karena itu tersedia untuk diubah sebelum tersedia di tempat lain (juga ditunjukkan di atas). Penting untuk dicatat bahwa variabel-variabel tersebut harus dilampirkan pada kata kunci 'ini'. Dalam contoh kita, hanya 'thingFromConfig' yang akan tersedia untuk diubah di app.config. Bagian ketiga (diperlihatkan di bawah) adalah semua variabel / fungsi yang akan tersedia di controller Anda ketika Anda memasukkan layanan 'myProvider' ke controller spesifik itu.
Saat membuat layanan dengan Penyedia, satu-satunya properti / metode yang akan tersedia di controller Anda adalah properti / metode yang dikembalikan dari fungsi $ get (). Kode di bawah ini menempatkan $ get pada 'this' (yang kita tahu pada akhirnya akan dikembalikan dari fungsi itu). Sekarang, fungsi $ get mengembalikan semua metode / properti yang kita inginkan tersedia di controller. Ini contoh kode.
Sekarang kode Penyedia lengkap terlihat seperti ini
app.provider('myProvider',function(){var baseUrl ='https://itunes.apple.com/search?term=';var _artist ='';var _finalUrl ='';//Going to set this property on the config function belowthis.thingFromConfig ='';var makeUrl =function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist +'&callback=JSON_CALLBACK'return _finalUrl;}this.$get =function($http, $q){return{
callItunes:function(){
makeUrl();var deferred = $q.defer();
$http({
method:'JSONP',
url: _finalUrl
}).success(function(data){
deferred.resolve(data);}).error(function(){
deferred.reject('There was an error')})return deferred.promise;},
setArtist:function(artist){
_artist = artist;},
getArtist:function(){return _artist;},
thingOnConfig:this.thingFromConfig
}}});
Sekarang sama seperti di pabrik dan Layanan kami, setArtist, getArtist, dan callItunes akan tersedia di mana pun pengendali tempat kami memberikan myProvider. Inilah pengontrol myProvider (yang hampir persis sama dengan pengontrol pabrik / Layanan kami).
Seperti yang disebutkan sebelumnya, inti dari menciptakan layanan dengan Penyedia adalah untuk dapat mengubah beberapa variabel melalui fungsi app.config sebelum objek terakhir diteruskan ke sisa aplikasi. Mari kita lihat contohnya.
app.config(function(myProviderProvider){//Providers are the only service you can pass into app.config
myProviderProvider.thingFromConfig ='This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works';});
Sekarang Anda dapat melihat bagaimana 'thingFromConfig' sebagai string kosong di penyedia kami, tetapi ketika itu muncul di DOM, itu akan menjadi 'Kalimat ini telah ditetapkan ...'.
Satu-satunya bagian yang hilang dalam penulisan yang sangat baik ini adalah keuntungan relatif dari menggunakan layanan di atas pabrik; yang jelas dijelaskan dalam jawaban yang diterima oleh Lior
Bagian slogan 'JavaScript guru' adalah licik. : DI pikir jawaban ini sangat jelas. Ditulis dengan luar biasa.
amarmishra
4
TLDR Anda membutuhkan TLDR.
JensB
3
@JensB tl; dr - Pelajari Bereaksi.
Tyler McGinnis
512
Semua Layanan adalah lajang ; mereka akan instantiated sekali per aplikasi. Mereka bisa dari jenis apa pun , apakah itu primitif, objek literal, fungsi, atau bahkan turunan dari jenis kustom.
The value, factory, service, constant, dan providermetode yang semua penyedia. Mereka mengajarkan Injector bagaimana membuat Instansiasi Layanan.
Yang paling verbose, tetapi juga yang paling komprehensif adalah resep Provider. The tersisa empat jenis resep - Nilai, Pabrik, Jasa dan Constant - hanya sintaksis gula di atas resep penyedia .
The Nilai Resep adalah kasus yang paling sederhana, di mana Anda instantiate Layanan diri sendiri dan memberikan nilai instantiated ke injektor.
The Factory resep memberikan Injector fungsi pabrik yang mereka sebut saat dibutuhkan untuk instantiate layanan. Ketika dipanggil, fungsi pabrik membuat dan mengembalikan instance layanan. Ketergantungan Layanan disuntikkan sebagai argumen fungsi. Jadi menggunakan resep ini menambah kemampuan berikut:
Kemampuan untuk menggunakan layanan lain (memiliki ketergantungan)
Inisialisasi layanan
Inisialisasi tertunda / malas
The Resep Layanan ini hampir sama dengan resep Factory, tapi di sini Injector memanggil sebuah konstruktor dengan operator baru, bukan fungsi pabrik.
The Resep Provider biasanya berlebihan . Ini menambah satu lapisan tipuan dengan memungkinkan Anda untuk mengonfigurasi pembuatan pabrik.
Anda harus menggunakan resep Penyedia hanya ketika Anda ingin mengekspos API untuk konfigurasi seluruh aplikasi yang harus dibuat sebelum aplikasi dimulai. Ini biasanya menarik hanya untuk layanan yang dapat digunakan kembali yang perilakunya mungkin perlu sedikit berbeda di antara aplikasi.
The Resep Konstan adalah seperti Nilai resep kecuali memungkinkan Anda untuk menentukan layanan yang tersedia di config fase. Lebih cepat dari layanan yang dibuat menggunakan resep Nilai. Tidak seperti Nilai, mereka tidak dapat didekorasi dengan menggunakandecorator .
Jadi servis dan pabrik pada dasarnya sama? Menggunakan salah satu dari yang lain tidak memberikan apa pun selain sintaksis alternatif?
Matt
2
@ Matt, ya, layanan adalah cara ringkas ketika Anda sudah memiliki fungsi Anda sendiri yang ingin Anda paparkan sebagai layanan. Dari docs: myApp.factory ('unicornLauncher', ["apiToken", function (apiToken) {kembalikan UnicornLauncher baru (apiToken);}]); vs: myApp.service ('unicornLauncher', ["apiToken", UnicornLauncher]);
janek
5
@ joshperry Sebagai pemula, saya telah mencari Google perbedaan antara layanan dan pabrik untuk sementara waktu. Saya setuju ini adalah jawaban terbaik yang pernah ada! Saya memahami layanan sebagai kelas layanan (mis. Kelas encoder / decoder), yang mungkin memiliki beberapa properti pribadi. Dan pabrik menyediakan seperangkat metode pembantu tanpa kewarganegaraan.
stanleyxu2005
3
Contoh Yaa dalam jawaban lain di atas gagal menjelaskan dengan jelas perbedaan inti layanan dan penyedia b / w yang disuntikkan pada saat resep ini dipakai.
Ashish Singh
223
Memahami Pabrik, Layanan, dan Penyedia AngularJS
Semua ini digunakan untuk berbagi objek singleton yang dapat digunakan kembali. Ini membantu untuk membagikan kode yang dapat digunakan kembali di aplikasi Anda / berbagai komponen / modul.
Instanated Lazily - Angular hanya instantiate layanan / pabrik ketika komponen aplikasi bergantung padanya.
Singletons - Setiap komponen yang bergantung pada layanan mendapat referensi ke instance tunggal yang dihasilkan oleh pabrik layanan.
Pabrik
Pabrik adalah fungsi tempat Anda dapat memanipulasi / menambahkan logika sebelum membuat objek, lalu objek yang baru dibuat akan dikembalikan.
app.factory('MyFactory',function(){var serviceObj ={};//creating an object with methods/functions or variables
serviceObj.myFunction =function(){//TO DO:};//return that objectreturn serviceObj;});
Pemakaian
Ini bisa jadi hanya kumpulan fungsi seperti kelas. Oleh karena itu, ini dapat dipakai di pengontrol yang berbeda ketika Anda menyuntikkannya di dalam fungsi pengontrol / pabrik / direktif Anda. Ini dipakai hanya sekali per aplikasi.
Layanan
Cukup sambil melihat layanan berpikir tentang prototipe array. Layanan adalah fungsi yang membuat objek baru menggunakan kata kunci 'baru'. Anda dapat menambahkan properti dan fungsi ke objek layanan dengan menggunakan thiskata kunci. Tidak seperti pabrik, itu tidak mengembalikan apa pun (itu mengembalikan objek yang berisi metode / properti).
app.service('MyService',function(){//directly binding events to this contextthis.myServiceFunction =function(){//TO DO:};});
Pemakaian
Gunakan saat Anda perlu membagikan satu objek di seluruh aplikasi. Misalnya, rincian pengguna yang diautentikasi, metode / data yang dapat dibagikan, fungsi Utilitas dll.
Pemberi
Penyedia digunakan untuk membuat objek layanan yang dapat dikonfigurasi. Anda dapat mengonfigurasi pengaturan layanan dari fungsi konfigurasi. Ini mengembalikan nilai dengan menggunakan $get()fungsi. The $getFungsi dijalankan pada fase run di sudut.
app.provider('configurableService',function(){var name ='';//this method can be be available at configuration time inside app.config.this.setName =function(newName){
name = newName;};this.$get =function(){var getName =function(){return name;};return{
getName: getName //exposed object to where it gets injected.};};});
Pemakaian
Ketika Anda perlu memberikan konfigurasi bijaksana untuk objek layanan Anda sebelum membuatnya tersedia, misalnya. misalkan Anda ingin mengatur URL API Anda berdasarkan Lingkungan Anda seperti dev, stageatauprod
CATATAN
Hanya penyedia yang akan tersedia dalam fase konfigurasi sudut, sementara layanan & pabrik tidak.
Semoga ini telah menjernihkan pemahaman Anda tentang Pabrik, Layanan, dan Penyedia .
Apa yang akan saya lakukan jika saya ingin memiliki layanan dengan antarmuka tertentu, tetapi memiliki dua implementasi yang berbeda, dan menyuntikkan masing-masing ke controller tetapi terikat ke berbagai negara menggunakan ui-router? misalnya membuat panggilan jarak jauh di satu negara, tetapi menulis ke penyimpanan lokal sebagai gantinya di negara lain. Dokumen penyedia mengatakan untuk digunakan only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications, jadi sepertinya tidak mungkin, kan?
qix
191
Bagi saya, wahyu datang ketika saya menyadari bahwa mereka semua bekerja dengan cara yang sama: dengan menjalankan sesuatu sekali , menyimpan nilai yang mereka dapatkan, dan kemudian batuk nilai tersimpan yang sama ketika direferensikan melalui injeksi ketergantungan .
cNilai yang disimpan berasal dari pertama mendapatkan instance dengan newing fn, dan kemudian menjalankan $getmetode instance.
Yang berarti ada sesuatu seperti objek cache di dalam AngularJS, yang nilainya setiap injeksi hanya diberikan satu kali, ketika mereka telah disuntikkan pertama kali, dan di mana:
Saya juga paling suka jawaban ini. Inti dari semuanya adalah untuk menyediakan akses ke suatu objek kapan pun dibutuhkan melalui DI. Biasanya Anda baik-baik saja dengan factorys. Satu-satunya alasan serviceyang ada adalah bahasa seperti CoffeeScript, TypeScript, ES6 dll. Sehingga Anda dapat menggunakan sintaks kelasnya. Anda providerhanya perlu jika modul Anda digunakan di beberapa aplikasi dengan pengaturan yang berbeda dengan menggunakan app.config(). Jika layanan Anda adalah singleton murni atau mampu membuat instance sesuatu hanya tergantung pada implementasi Anda.
Andreas Linnert
137
Layanan vs penyedia vs pabrik:
Saya mencoba membuatnya tetap sederhana. Ini semua tentang konsep dasar JavaScript.
Pertama-tama, mari kita bicara tentang layanan di AngularJS!
Apa itu Layanan:
Di AngularJS, Layanantidak lain adalah objek JavaScript tunggal yang dapat menyimpan beberapa metode atau properti yang berguna. Objek tunggal ini dibuat per ngApp (aplikasi Angular) dan dibagi di antara semua pengontrol dalam aplikasi saat ini. Ketika Angularjs instantiate objek layanan, itu mendaftarkan objek layanan ini dengan nama layanan yang unik. Jadi setiap kali ketika kita membutuhkan instance layanan, Angular mencari registri untuk nama layanan ini, dan mengembalikan referensi ke objek layanan. Sehingga kita dapat memanggil metode, mengakses properti dll pada objek layanan. Anda mungkin memiliki pertanyaan apakah Anda juga dapat menempatkan properti, metode pada objek lingkup pengontrol! Jadi mengapa Anda membutuhkan objek layanan? Jawabannya adalah: layanan dibagi di antara beberapa lingkup pengontrol. Jika Anda meletakkan beberapa properti / metode dalam objek lingkup pengontrol, itu akan tersedia untuk lingkup saat ini saja.
Jadi jika ada tiga ruang lingkup pengontrol, misalkan pengontrolA, pengontrolB dan pengontrolC, semua akan berbagi layanan yang sama.
AngularJS menyediakan berbagai metode untuk mendaftarkan layanan. Di sini kita akan berkonsentrasi pada tiga metode factory (..), service (..), provider (..);
AngularJS menyediakan metode 'factory (' serviceName ', fnFactory)' yang mengambil dua parameter, serviceName dan fungsi JavaScript. Angular membuat instance layanan dengan menjalankan fungsi fnFactory () seperti di bawah ini.
var serviceInstace = fnFactory();
Fungsi yang diteruskan dapat mendefinisikan objek dan mengembalikan objek itu. AngularJS hanya menyimpan referensi objek ini ke variabel yang diteruskan sebagai argumen pertama. Apa pun yang dikembalikan dari fnFactory akan terikat ke serviceInstance. Alih-alih mengembalikan objek, kita juga dapat mengembalikan fungsi, nilai, dll. Apapun yang akan kita kembalikan, akan tersedia untuk instance layanan.
Contoh:
var app= angular.module('myApp',[]);//creating service using factory method
app.factory('factoryPattern',function(){var data={'firstName':'Tom','lastName':' Cruise',
greet:function(){
console.log('hello!'+this.firstName +this.lastName);}};//Now all the properties and methods of data object will be available in our service objectreturn data;});
Ini cara lain, kita bisa mendaftarkan layanan. Satu-satunya perbedaan adalah cara AngularJS mencoba untuk instantiate objek layanan. Kali ini sudut menggunakan kata kunci 'baru' dan memanggil fungsi konstruktor seperti di bawah ini.
var serviceInstance =new fnServiceConstructor();
Dalam fungsi konstruktor kita dapat menggunakan kata kunci 'ini' untuk menambahkan properti / metode ke objek layanan. contoh:
//Creating a service using the service methodvar app= angular.module('myApp',[]);
app.service('servicePattern',function(){this.firstName ='James';this.lastName =' Bond';this.greet =function(){
console.log('My Name is '+this.firstName +this.lastName);};});
Fungsi penyedia:
Fungsi Provider () adalah cara lain untuk membuat layanan. Biarkan kami tertarik untuk membuat layanan yang hanya menampilkan beberapa pesan ucapan kepada pengguna. Tetapi kami juga ingin menyediakan fungsionalitas sehingga pengguna dapat mengatur pesan ucapan mereka sendiri. Dalam istilah teknis kami ingin membuat layanan yang dapat dikonfigurasi. Bagaimana kita bisa melakukan ini? Harus ada cara, sehingga aplikasi dapat mengirimkan pesan ucapan khusus mereka dan Angular akan membuatnya tersedia untuk fungsi pabrik / konstruktor yang membuat instance layanan kami. Dalam hal ini penyedia fungsi () melakukan pekerjaan. menggunakan fungsi provider () kita dapat membuat layanan yang dapat dikonfigurasi.
Kami dapat membuat layanan yang dapat dikonfigurasi menggunakan sintaksis penyedia seperti yang diberikan di bawah ini.
/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});/*step2:configure the service */
app.config(function configureService(serviceProvider){});
Bagaimana cara kerja sintaksis penyedia secara internal?
1.Provider object dibuat menggunakan fungsi konstruktor yang kami definisikan dalam fungsi provider kami.
var serviceProvider =new serviceProviderConstructor();
2.Fungsi yang kami lewati di app.config (), dijalankan. Ini disebut tahap konfigurasi, dan di sini kami memiliki kesempatan untuk menyesuaikan layanan kami.
configureService(serviceProvider);
3. Akhirnya layanan dibuat dengan memanggil metode $ get dari serviceProvider.
serviceInstance = serviceProvider.$get()
Kode sampel untuk membuat layanan menggunakan sintaks menyediakan:
var app= angular.module('myApp',[]);
app.provider('providerPattern',function providerConstructor(){//this function works as constructor function for providerthis.firstName ='Arnold ';this.lastName =' Schwarzenegger';this.greetMessage =' Welcome, This is default Greeting Message';//adding some method which we can call in app.config() functionthis.setGreetMsg =function(msg){if(msg){this.greetMessage = msg ;}};//We can also add a method which can change firstName and lastNamethis.$get =function(){var firstName =this.firstName;var lastName =this.lastName ;var greetMessage =this.greetMessage;var data={
greet:function(){
console.log('hello, '+ firstName + lastName+'! '+ greetMessage);}};return data ;};});
app.config(function(providerPatternProvider){
providerPatternProvider.setGreetMsg(' How do you do ?');});
Pabrik menggunakan fungsi pabrik yang mengembalikan instance layanan.
serviceInstance = fnFactory ();
Layanan menggunakan fungsi konstruktor dan Angular memanggil fungsi konstruktor ini menggunakan kata kunci 'baru' untuk membuat turunan layanan.
serviceInstance = new fnServiceConstructor ();
Penyedia mendefinisikan fungsi providerConstructor, fungsi providerConstructor ini mendefinisikan fungsi pabrik $ get . Panggilan sudut $ get () untuk membuat objek layanan. Sintaks penyedia memiliki keuntungan tambahan untuk mengkonfigurasi objek layanan sebelum instantiated.
serviceInstance = $ get ();
Seperti yang ditunjukkan oleh beberapa orang di sini dengan benar pabrik, penyedia, layanan, dan bahkan nilai dan konstan adalah versi dari hal yang sama. Anda dapat membedah yang lebih umum providermenjadi semuanya. Seperti itu:
Anda memberi AngularJS fungsi, AngularJS akan memanggil baru untuk membuat instance. Ini adalah contoh yang dibuat AngularJS yang akan di-cache dan disuntikkan ketika layanan diminta. Karena baru digunakan untuk membuat instantiate layanan, kata kunci ini valid dan merujuk ke instance.
Contoh:
app.service('service',function(){var name ='';this.setName =function(newName){
name = newName;}this.getName =function(){return name;}});
Anda memberi AngularJS fungsi, dan AngularJS akan memanggil $getfungsinya. Ini adalah nilai balik dari $getfungsi yang akan di-cache dan disuntikkan ketika layanan diminta.
Penyedia memungkinkan Anda untuk mengkonfigurasi penyedia sebelum AngularJS memanggil $getmetode untuk mendapatkan injeksi.
Contoh:
app.provider('provider',function(){var name ='';this.setName =function(newName){
name = newName;}this.$get =function(){return{
name: name
}}})
Saya perhatikan sesuatu yang menarik ketika bermain-main dengan penyedia.
Visibilitas dari suntikan berbeda untuk penyedia daripada untuk layanan dan pabrik. Jika Anda menyatakan AngularJS "konstan" (misalnya, myApp.constant('a', 'Robert');), Anda dapat menyuntikkannya ke layanan, pabrik, dan penyedia.
Tetapi jika Anda mendeklarasikan "nilai" AngularJS (misalnya., myApp.value('b', {name: 'Jones'});), Anda dapat menyuntikkannya ke layanan dan pabrik, tetapi BUKAN ke dalam fungsi pembuatan penyedia. Namun, Anda dapat menyuntikkannya ke $getfungsi yang Anda tetapkan untuk penyedia Anda. Ini disebutkan dalam dokumentasi AngularJS, tetapi mudah untuk dilewatkan. Anda dapat menemukannya di halaman% sediakan di bagian nilai dan metode konstan.
Ini adalah bagian yang sangat membingungkan bagi pemula dan saya telah mencoba menjelaskannya dengan kata-kata yang mudah
Layanan AngularJS: digunakan untuk berbagi fungsi utilitas dengan referensi layanan di controller. Layanan bersifat tunggal sehingga untuk satu layanan hanya satu instance yang dibuat di browser dan referensi yang sama digunakan di seluruh halaman.
Dalam layanan, kami membuat nama fungsi sebagai properti dengan objek ini .
AngularJS Factory: tujuan Factory juga sama dengan Service namun dalam hal ini kami membuat objek baru dan menambahkan fungsi sebagai properti dari objek ini dan pada akhirnya kami mengembalikan objek ini.
AngularJS Provider: tujuan ini sekali lagi sama namun Provider memberikan output fungsi $ get.
Jadi, untuk layanan, yang menjadi komponen AngularJS adalah instance objek dari kelas yang diwakili oleh fungsi deklarasi layanan. Untuk pabrik, itu adalah hasil yang dikembalikan dari fungsi deklarasi pabrik. Pabrik mungkin berperilaku sama dengan layanan:
var factoryAsService =function(injection){returnnewfunction(injection){// Service content}}
Cara berpikir paling sederhana adalah yang berikut:
Layanan adalah contoh objek tunggal. Gunakan layanan jika Anda ingin memberikan objek tunggal untuk kode Anda.
Pabrik adalah kelas. Gunakan pabrik jika Anda ingin memberikan kelas khusus untuk kode Anda (tidak dapat dilakukan dengan layanan karena mereka sudah dipakai)
Contoh 'kelas' pabrik diberikan dalam komentar di sekitar, serta perbedaan penyedia.
bagaimana sebuah layanan bisa menjadi singleton jika ia dipakai setiap kali digunakan? saya bisa mendapatkan kepala saya di sekitar itu ...
joe
Layanan hanya sekali dipakai selama penyelesaian ketergantungan, dan kemudian ketika Anda meminta layanan dari injector, Anda mendapatkan selalu contoh yang sama. Dapat dengan mudah memeriksa di sini: jsfiddle.net/l0co/sovtu55t/1 , silakan jalankan dengan konsol. Konsol menunjukkan bahwa layanan hanya dipakai satu kali.
Lukasz Frankowski
Oh begitu. Saya berharap untuk dapat secara harfiah new MyService()atau sesuatu :)
joe
33
Klarifikasi saya tentang masalah ini:
Pada dasarnya semua jenis yang disebutkan (layanan, pabrik, penyedia, dll.) Hanya membuat dan mengkonfigurasi variabel global (yang tentu saja global ke seluruh aplikasi), sama seperti variabel global kuno itu.
Sementara variabel global tidak direkomendasikan, penggunaan nyata dari variabel global ini adalah untuk memberikan injeksi ketergantungan , dengan meneruskan variabel ke pengontrol yang relevan.
Ada banyak tingkat komplikasi dalam menciptakan nilai untuk "variabel global":
Constant
Ini mendefinisikan konstanta aktual yang tidak boleh dimodifikasi selama keseluruhan aplikasi, seperti halnya konstanta dalam bahasa lain (sesuatu yang tidak dimiliki JavaScript).
Nilai
Ini adalah nilai atau objek yang dapat dimodifikasi, dan berfungsi sebagai beberapa variabel global, yang bahkan dapat disuntikkan ketika membuat layanan atau pabrik lain (lihat lebih lanjut tentang ini). Namun, itu harus berupa " nilai literal ", yang berarti bahwa seseorang harus menuliskan nilai aktual, dan tidak dapat menggunakan perhitungan atau logika pemrograman apa pun (dengan kata lain 39 atau myText atau {prop: "value"} tidak apa-apa, tetapi 2 +2 tidak).
Pabrik
Nilai yang lebih umum, yang memungkinkan untuk segera dihitung. Ia bekerja dengan melewatkan fungsi ke AngularJS dengan logika yang diperlukan untuk menghitung nilai dan AngularJS mengeksekusi itu, dan menyimpan nilai kembali dalam variabel bernama.
Perhatikan bahwa dimungkinkan untuk mengembalikan objek (dalam hal ini akan berfungsi mirip dengan layanan ) atau fungsi (yang akan disimpan dalam variabel sebagai fungsi panggilan balik).
Layanan
Suatu layanan adalah versi pabrik yang lebih sederhana yang hanya valid ketika nilainya adalah objek, dan memungkinkan untuk menulis logika apa pun secara langsung dalam fungsi (seolah-olah itu akan menjadi konstruktor), serta mendeklarasikan dan mengakses properti objek menggunakan kata kunci ini .
Penyedia
Tidak seperti layanan yang merupakan versi pabrik yang disederhanakan , penyedia adalah cara yang lebih kompleks, tetapi lebih fleksibel untuk menginisialisasi variabel "global", dengan fleksibilitas terbesar adalah opsi untuk menetapkan nilai dari app.config.
Ini berfungsi seperti menggunakan kombinasi layanan dan penyedia , dengan mengirimkan ke penyedia fungsi yang memiliki properti yang dideklarasikan menggunakan kata kunci ini , yang dapat digunakan dari app.config.
Maka ia perlu memiliki fungsi $ .get terpisah yang dijalankan oleh AngularJS setelah menyetel properti di atas melalui app.configfile, dan fungsi $ .get ini berlaku seperti pabrik. di atas, dalam nilai pengembaliannya digunakan untuk menginisialisasi variabel "global".
Apakah Anda tidak mencampuradukkan Pabrik dan Layanan? Layanan menciptakan tempat pabrik kembali.
Flavien Volken
Saat Anda mendeklarasikan nama layanan sebagai argumen yang dapat disuntikkan, Anda akan diberikan instance fungsi. Dengan kata lain FunctionYouPassedToService () baru. Contoh objek ini menjadi objek layanan yang didaftarkan dan disuntikkan AngularJS nanti ke layanan / pengendali lain jika diperlukan. // factory Ketika Anda mendeklarasikan factoryname sebagai argumen injeksi, Anda akan diberikan nilai yang dikembalikan dengan menggunakan referensi fungsi yang diteruskan ke module.factory.
sajan
Oke, jadi ... di sudut pabrik adalah singleton di mana "layanan" sebenarnya adalah pabrik (dalam istilah pola desain umum)
Pabrik dan Layanan adalah resep yang paling umum digunakan. Satu-satunya perbedaan di antara mereka adalah bahwa resep Layanan berfungsi lebih baik untuk objek jenis kustom, sementara Pabrik dapat menghasilkan primitif dan fungsi JavaScript.
The Provider resep adalah jenis resep inti dan semua yang lain yang hanya sintaksis gula di atasnya.
Penyedia adalah jenis resep paling kompleks. Anda tidak memerlukannya kecuali Anda sedang membangun sepotong kode yang dapat digunakan kembali yang membutuhkan konfigurasi global.
Semua jawaban bagus sudah. Saya ingin menambahkan beberapa poin lagi pada Layanan dan Pabrik . Seiring dengan perbedaan antara layanan / pabrik. Dan seseorang juga dapat memiliki pertanyaan seperti:
Haruskah saya menggunakan layanan atau pabrik? Apa bedanya?
Apakah mereka melakukan hal yang sama atau memiliki perilaku yang sama?
Mari kita mulai dengan perbedaan antara Layanan dan pabrik:
Keduanya Singletons : Setiap kali Angular menemukan ini sebagai dependensi pertama kali, itu membuat contoh layanan / pabrik. Setelah instance dibuat, instance yang sama digunakan selamanya.
Dapat digunakan untuk memodelkan objek dengan perilaku : Keduanya dapat memiliki metode, variabel status internal, dan sebagainya. Meskipun cara Anda menulis kode itu akan berbeda.
Jasa:
Layanan adalah fungsi konstruktor, dan Angular akan instantiate dengan memanggil baru yourServiceName(). Ini berarti beberapa hal.
Fungsi dan variabel instan akan menjadi properti dari this .
Anda tidak perlu mengembalikan nilai. Ketika panggilan Angular new yourServiceName(), ia akan menerima thisobjek dengan semua properti yang Anda masukkan.
Ketika Angular menyuntikkan MyServicelayanan ini ke pengontrol yang bergantung padanya, pengontrol itu akan mendapatkan layanan MyServiceyang dapat memanggil fungsi, misalnya MyService.aServiceMethod ().
Hati-hati denganthis :
Karena layanan yang dibangun adalah objek, metode di dalamnya dapat merujuk ini ketika mereka dipanggil:
Anda mungkin tergoda untuk memanggil ScoreKeeper.setScorerantai janji, misalnya jika Anda menginisialisasi skor dengan meraihnya dari server: $http.get('/score').then(ScoreKeeper.setScore).Masalahnya adalah ini ScoreKeeper.setScoreakan dipanggil dengan thisterikat nulldan Anda akan mendapatkan kesalahan. Cara yang lebih baik$http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper)) . Apakah Anda memilih untuk menggunakan ini dalam metode layanan Anda atau tidak, berhati-hatilah bagaimana Anda menyebutnya.
Mengembalikan Nilai dari a Service :
Karena cara kerja konstruktor JavaScript, jika Anda mengembalikan nilai kompleks (i.e., an Object)dari aconstructor fungsi, pemanggil akan mendapatkan Objek itu daripada instance ini.
Ini berarti bahwa Anda pada dasarnya dapat menyalin-menempelkan contoh pabrik dari bawah, ganti factorydengan service, dan itu akan berhasil:
angular.service('MyService',function($http){var api ={};
api.aServiceMethod=function(){return $http.get('/users');};return api;});
Jadi ketika Angular membangun layanan Anda dengan MyService baru (), ia akan mendapatkan objek api itu alih-alih instance MyService.
Ini adalah perilaku untuk setiap nilai kompleks (objek, fungsi) tetapi tidak untuk tipe primitif.
Pabrik:
Pabrik adalah fungsi lama sederhana yang mengembalikan nilai. Nilai pengembalian adalah apa yang disuntikkan ke dalam hal-hal yang bergantung pada pabrik. Pola khas pabrik di Angular adalah mengembalikan objek dengan fungsi sebagai properti, seperti ini:
angular.factory('MyFactory',function($http){var api ={};
api.aFactoryMethod=function(){return $http.get('/users');};return api;});
Nilai yang disuntikkan untuk ketergantungan pabrik adalah nilai pengembalian pabrik, dan tidak harus menjadi objek. Bisa jadi fungsi
Jawaban untuk pertanyaan 1 dan 2 di atas:
Untuk sebagian besar, tetap menggunakan pabrik untuk semuanya. Perilaku mereka lebih mudah dipahami. Tidak ada pilihan untuk membuat apakah akan mengembalikan nilai atau tidak, dan lebih jauh, tidak ada bug yang akan diperkenalkan jika Anda melakukan hal yang salah.
Saya masih menyebutnya sebagai "layanan" ketika saya berbicara tentang menyuntikkan mereka sebagai dependensi.
Perilaku Servis / Pabrik sangat mirip, dan beberapa orang akan mengatakan bahwa keduanya baik-baik saja. Itu agak benar, tetapi saya merasa lebih mudah untuk mengikuti saran dari panduan gaya John Papa dan hanya tetap dengan pabrik. **
Sudah ada jawaban bagus, tapi saya hanya ingin membagikan yang ini.
Pertama-tama: Penyedia adalah cara / resep untuk membuatservice (objek tunggal) yang seharusnya disuntikkan oleh $ injector (bagaimana AngulaJS berjalan tentang pola IoC).
Dan Nilai, Pabrik, Layanan dan Konstan (4 cara) - gula sintaksis atas Penyedia cara / penerima.
Layanan adalah tentang newkata kunci sebenarnya yang seperti yang kita ketahui melakukan 4 hal:
menciptakan objek baru
menautkannya ke prototype objeknya
menghubungkan context kethis
dan kembali this
Dan Pabrik adalah semua tentang Pola Pabrik - berisi fungsi yang mengembalikan Objek seperti Layanan itu.
kemampuan untuk menggunakan layanan lain (memiliki ketergantungan)
inisialisasi layanan
inisialisasi tertunda / malas
Dan video sederhana / singkat ini: mencakup juga Penyedia : https://www.youtube.com/watch?v=HvTZbQ_hUZY (di sana Anda dapat melihat bagaimana mereka beralih dari satu pabrik ke penyedia lainnya)
Resep penyedia sebagian besar digunakan dalam konfigurasi aplikasi, sebelum aplikasi sepenuhnya dimulai / diinisialisasi.
Setelah membaca semua posting ini, itu membuat saya lebih bingung .. Tapi tetap saja semua informasi berharga .. akhirnya saya menemukan tabel berikut yang akan memberikan informasi dengan perbandingan sederhana
Injektor menggunakan resep untuk membuat dua jenis objek: layanan dan objek tujuan khusus
Ada lima jenis resep yang menentukan cara membuat objek: Nilai, Pabrik, Layanan, Penyedia, dan Konstan.
Pabrik dan Layanan adalah resep yang paling umum digunakan. Satu-satunya perbedaan di antara mereka adalah bahwa resep Layanan berfungsi lebih baik untuk objek jenis kustom, sementara Pabrik dapat menghasilkan primitif dan fungsi JavaScript.
Resep Provider adalah tipe resep inti dan yang lainnya hanyalah gula sintaksis.
Penyedia adalah jenis resep paling kompleks. Anda tidak memerlukannya kecuali Anda sedang membangun sepotong kode yang dapat digunakan kembali yang membutuhkan konfigurasi global.
Semua objek tujuan khusus kecuali untuk Kontroler didefinisikan melalui resep Pabrik.
Dan untuk pemula pahami: - Ini mungkin tidak memperbaiki use case tetapi pada level tinggi inilah yang digunakan untuk ketiganya.
Jika Anda ingin menggunakan fungsi konfigurasi modul sudut harus dibuat sebagai penyedia
Berikut adalah beberapa kode platfile yang saya buat sebagai templat kode untuk objek pabrik di AngularjS. Saya telah menggunakan Car / CarFactory sebagai contoh untuk menggambarkan. Membuat kode implementasi sederhana di controller.
<script>
angular.module('app',[]).factory('CarFactory',function(){/**
* BroilerPlate Object Instance Factory Definition / Example
*/this.Car=function(){// initialize instance properties
angular.extend(this,{
color :null,
numberOfDoors :null,
hasFancyRadio :null,
hasLeatherSeats :null});// generic setter (with optional default value)this.set=function(key, value, defaultValue, allowUndefined){// by default,if(typeof allowUndefined ==='undefined'){// we don't allow setter to accept "undefined" as a value
allowUndefined =false;}// if we do not allow undefined values, and..if(!allowUndefined){// if an undefined value was passed inif(value ===undefined){// and a default value was specifiedif(defaultValue !==undefined){// use the specified default value
value = defaultValue;}else{// otherwise use the class.prototype.defaults value
value =this.defaults[key];}// end if/else}// end if}// end if// update this[key]= value;// return reference to this object (fluent)returnthis;};// end this.set()};// end this.Car class definition// instance properties default valuesthis.Car.prototype.defaults ={
color:'yellow',
numberOfDoors:2,
hasLeatherSeats:null,
hasFancyRadio:false};// instance factory method / constructorthis.Car.prototype.instance =function(params){returnnewthis.constructor().set('color', params.color).set('numberOfDoors', params.numberOfDoors).set('hasFancyRadio', params.hasFancyRadio).set('hasLeatherSeats', params.hasLeatherSeats);};returnnewthis.Car();})// end Factory Definition.controller('testCtrl',function($scope,CarFactory){
window.testCtrl = $scope;// first car, is red, uses class default for:// numberOfDoors, and hasLeatherSeats
$scope.car1 =CarFactory.instance({
color:'red'});// second car, is blue, has 3 doors, // uses class default for hasLeatherSeats
$scope.car2 =CarFactory.instance({
color:'blue',
numberOfDoors:3});// third car, has 4 doors, uses class default for // color and hasLeatherSeats
$scope.car3 =CarFactory.instance({
numberOfDoors:4});// sets an undefined variable for 'hasFancyRadio',// explicitly defines "true" as default when value is undefined
$scope.hasFancyRadio =undefined;
$scope.car3.set('hasFancyRadio', $scope.hasFancyRadio,true);// fourth car, purple, 4 doors,// uses class default for hasLeatherSeats
$scope.car4 =CarFactory.instance({
color:'purple',
numberOfDoors:4});// and then explicitly sets hasLeatherSeats to undefined
$scope.hasLeatherSeats =undefined;
$scope.car4.set('hasLeatherSeats', $scope.hasLeatherSeats,undefined,true);// in console, type window.testCtrl to see the resulting objects});</script>
Ini adalah contoh sederhana. Saya menggunakan beberapa pustaka pihak ketiga yang mengharapkan objek "Posisi" yang mengekspos lintang dan bujur, tetapi melalui properti objek yang berbeda. Saya tidak ingin meretas kode vendor, jadi saya menyesuaikan objek "Posisi" yang saya berikan.
angular.module('app').factory('PositionFactory',function(){/**
* BroilerPlate Object Instance Factory Definition / Example
*/this.Position=function(){// initialize instance properties // (multiple properties to satisfy multiple external interface contracts)
angular.extend(this,{
lat :null,
lon :null,
latitude :null,
longitude :null,
coords:{
latitude:null,
longitude:null}});this.setLatitude =function(latitude){this.latitude = latitude;this.lat = latitude;this.coords.latitude = latitude;returnthis;};this.setLongitude =function(longitude){this.longitude = longitude;this.lon = longitude;this.coords.longitude = longitude;returnthis;};};// end class definition// instance factory method / constructorthis.Position.prototype.instance =function(params){returnnewthis.constructor().setLatitude(params.latitude).setLongitude(params.longitude);};returnnewthis.Position();})// end Factory Definition.controller('testCtrl',function($scope,PositionFactory){
$scope.position1 =PositionFactory.instance({latitude:39, longitude:42.3123});
$scope.position2 =PositionFactory.instance({latitude:39, longitude:42.3333});})// end controller
Menggunakan referensi halaman ini dan dokumentasi (yang tampaknya telah sangat meningkat sejak terakhir kali saya melihat), saya mengumpulkan demo dunia nyata (-ish) berikut ini yang menggunakan 4 dari 5 rasa penyedia; Penyedia Nilai, Konstan, Pabrik, dan peniupan penuh.
HTML:
<divng-controller="mainCtrl as main"><h1>{{main.title}}*</h1><h2>{{main.strapline}}</h2><p>Earn {{main.earn}} per click</p><p>You've earned {{main.earned}} by clicking!</p><buttonng-click="main.handleClick()">Click me to earn</button><small>* Not actual money</small></div>
aplikasi
var app = angular.module('angularProviders',[]);// A CONSTANT is not going to change
app.constant('range',100);// A VALUE could change, but probably / typically doesn't
app.value('title','Earn money by clicking');
app.value('strapline','Adventures in ng Providers');// A simple FACTORY allows us to compute a value @ runtime.// Furthermore, it can have other dependencies injected into it such// as our range constant.
app.factory('random',function randomFactory(range){// Get a random number within the range defined in our CONSTANTreturnMath.random()* range;});// A PROVIDER, must return a custom type which implements the functionality // provided by our service (see what I did there?).// Here we define the constructor for the custom type the PROVIDER below will // instantiate and return.varMoney=function(locale){// Depending on locale string set during config phase, we'll// use different symbols and positioning for any values we // need to display as currencythis.settings ={
uk:{
front:true,
currency:'£',
thousand:',',decimal:'.'},
eu:{
front:false,
currency:'€',
thousand:'.',decimal:','}};this.locale = locale;};// Return a monetary value with currency symbol and placement, and decimal // and thousand delimiters according to the locale set in the config phase.Money.prototype.convertValue =function(value){var settings =this.settings[this.locale],
decimalIndex, converted;
converted =this.addThousandSeparator(value.toFixed(2), settings.thousand);
decimalIndex = converted.length -3;
converted = converted.substr(0, decimalIndex)+
settings.decimal+
converted.substr(decimalIndex +1);
converted = settings.front ?
settings.currency + converted :
converted + settings.currency;return converted;};// Add supplied thousand separator to supplied valueMoney.prototype.addThousandSeparator =function(value, symbol){returnvalue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, symbol);};// PROVIDER is the core recipe type - VALUE, CONSTANT, SERVICE & FACTORY// are all effectively syntactic sugar built on top of the PROVIDER construct// One of the advantages of the PROVIDER is that we can configure it before the// application starts (see config below).
app.provider('money',functionMoneyProvider(){var locale;// Function called by the config to set up the providerthis.setLocale =function(value){
locale =value;};// All providers need to implement a $get method which returns// an instance of the custom class which constitutes the servicethis.$get =function moneyFactory(){returnnewMoney(locale);};});// We can configure a PROVIDER on application initialisation.
app.config(['moneyProvider',function(moneyProvider){
moneyProvider.setLocale('uk');//moneyProvider.setLocale('eu'); }]);// The ubiquitous controller
app.controller('mainCtrl',function($scope, title, strapline, random, money){// Plain old VALUE(s)this.title = title;this.strapline = strapline;this.count =0;// Compute values using our money provider this.earn = money.convertValue(random);// random is computed @ runtimethis.earned = money.convertValue(0);this.handleClick =function(){this.count ++;this.earned = money.convertValue(random *this.count);};});
bagaimana Factory, Service dan Constant - hanya gula sintaksis di atas resep penyedia?
ATAU
bagaimana pabrik, layanan dan penyedia simailar secara internal
pada dasarnya yang terjadi adalah
Ketika Anda membuatnya factory()menetapkan Anda functionberikan dalam argumen kedua ke penyedia $getdan mengembalikannya ( provider(name, {$get:factoryFn })), yang Anda dapatkan hanyalah providertetapi tidak ada properti / metode selain$get itu provider(artinya Anda tidak dapat mengonfigurasi ini)
Ketika membuatnya service()mengembalikan Anda memberikan pabrik () dengan functionyang menyuntikkan constructor(mengembalikan instance dari konstruktor yang Anda berikan dalam layanan Anda) dan mengembalikannya
Kode sumber layanan
function service(name,constructor){return factory(name,['$injector',function($injector){return $injector.instantiate(constructor);}]);};
Jadi pada dasarnya dalam kedua kasus Anda akhirnya mendapatkan penyedia $ bisa diatur untuk fungsi yang Anda berikan, tetapi Anda bisa memberikan apa pun lebih dari $ dapatkan karena Anda awalnya dapat menyediakan di provider () untuk blok konfigurasi
Saya tahu banyak jawaban yang sangat baik tetapi saya harus berbagi pengalaman saya menggunakan
1. serviceuntuk sebagian besar kasus default
2. factorydigunakan untuk membuat layanan contoh khusus
Agak terlambat ke pesta. Tapi saya pikir ini lebih bermanfaat bagi yang ingin belajar (atau memiliki kejelasan) tentang pengembangan Layanan Kustom JS Angular menggunakan metodologi pabrik, layanan, dan penyedia.
Saya menemukan video ini yang menjelaskan dengan jelas tentang metodologi pabrik, layanan, dan penyedia untuk mengembangkan Layanan Kustom AngularJS:
Kode yang diposting di sini disalin langsung dari sumber di atas, untuk memberi manfaat bagi pembaca.
Kode untuk layanan kustom berbasis "pabrik" adalah sebagai berikut (yang berlaku dengan versi sinkronisasi dan async bersamaan dengan memanggil layanan http):
Akhirnya UI yang bekerja dengan salah satu layanan di atas:
<html><head><title></title><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script><scripttype="text/javascript"src="t03.js"></script></head><bodyng-app="app"><divng-controller="emp"><div>
Value of a is {{a}},
but you can change
<inputtype=textng-model="a"/><br>
Value of b is {{b}},
but you can change
<inputtype=textng-model="b"/><br></div>
Sum = {{sum}}<br><buttonng-click="doSum()">Calculate</button></div></body></html>
Mari kita bahas tiga cara menangani logika bisnis di AngularJS dengan cara sederhana: ( Terinspirasi oleh kursus Coursera AngularJS Yaakov )
LAYANAN :
Sintaksis:
app.js
var app = angular.module('ServiceExample',[]);var serviceExampleController =
app.controller('ServiceExampleController',ServiceExampleController);var serviceExample = app.service('NameOfTheService',NameOfTheService);ServiceExampleController.$inject =['NameOfTheService']//protects from minification of js filesfunctionServiceExampleController(NameOfTheService){
serviceExampleController =this;
serviceExampleController.data =NameOfTheService.getSomeData();}functionNameOfTheService(){
nameOfTheService =this;
nameOfTheService.data ="Some Data";
nameOfTheService.getSomeData =function(){return nameOfTheService.data;}}
index.html
<divng-controller="ServiceExampleController as serviceExample">
{{serviceExample.data}}
</div>
Fitur Layanan:
Lazily Instantiated : Jika tidak disuntikkan, ia tidak akan pernah dipakai. Jadi untuk menggunakannya harus menyuntikkannya ke modul.
Singleton : Jika disuntikkan ke beberapa modul, semua akan memiliki akses hanya ke satu instance tertentu. Itu sebabnya sangat nyaman untuk berbagi data di seluruh pengontrol yang berbeda.
PABRIK
Pertama mari kita lihat sintaks:
app.js :
var app = angular.module('FactoryExample',[]);var factoryController = app.controller('FactoryController',FactoryController);var factoryExampleOne = app.factory('NameOfTheFactoryOne',NameOfTheFactoryOne);var factoryExampleTwo = app.factory('NameOfTheFactoryTwo',NameOfTheFactoryTwo);//first implementation where it returns a functionfunctionNameOfTheFactoryOne(){var factory =function(){returnnewSomeService();}return factory;}//second implementation where an object literal would be returnedfunctionNameOfTheFactoryTwo(){var factory ={
getSomeService :function(){returnnewSomeService();}};return factory;}
Sekarang menggunakan dua di atas di controller:
var factoryOne =NameOfTheFactoryOne()//since it returns a function
factoryOne.someMethod();var factoryTwo =NameOfTheFactoryTwo.getSomeService();//accessing the object
factoryTwo.someMethod();
Fitur pabrik:
Mengikuti pola desain pabrik. Pabrik adalah tempat sentral yang menghasilkan benda atau fungsi baru.
Tidak hanya menghasilkan singleton, tetapi layanan yang dapat disesuaikan.
The .service()Metode adalah pabrik yang selalu menghasilkan jenis yang sama dari layanan, yang tunggal, dan tanpa cara mudah untuk mengkonfigurasi perilaku itu. Itu .service()metode biasanya digunakan sebagai jalan pintas untuk sesuatu yang tidak memerlukan apapun konfigurasi.
Penyedia adalah metode yang paling fleksibel untuk menciptakan layanan di Angular.
Tidak hanya kita dapat membuat pabrik yang dapat dikonfigurasi secara dinamis, tetapi pada saat menggunakan pabrik, dengan metode penyedia, kita dapat mengkustomisasi pabrik hanya sekali pada saat bootstrap seluruh aplikasi kita.
Pabrik kemudian dapat digunakan di seluruh aplikasi dengan pengaturan khusus. Dengan kata lain, kita dapat mengkonfigurasi pabrik ini sebelum aplikasi dimulai. Bahkan dalam dokumentasi sudut disebutkan bahwa metode penyedia adalah apa yang sebenarnya dieksekusi di belakang layar ketika kita mengkonfigurasi layanan kami dengan salah satu .serviceatau .factorymetode.
Ini $getadalah fungsi yang secara langsung dilampirkan ke instance penyedia. Fungsi itu adalah fungsi pabrik . Dengan kata lain, itu hanya seperti salah satu yang kita gunakan untuk memberikan kepada .factorymetode. Dalam fungsi itu, kami membuat layanan kami sendiri. Properti ini $get, itulah fungsi, yang membuat penyedia menjadi penyedia . AngularJS mengharapkan penyedia memiliki properti $ get yang nilainya merupakan fungsi yang akan diperlakukan Angular sebagai fungsi pabrik. Tetapi apa yang membuat seluruh pengaturan penyedia ini sangat istimewa, adalah kenyataan bahwa kami dapat menyediakan beberapa configobjek di dalam penyedia layanan, dan yang biasanya disertai dengan default yang nantinya dapat kami timpa dalam langkah tersebut, di mana kami dapat mengonfigurasi seluruh aplikasi.
Pabrik: Pabrik Anda benar-benar membuat objek di dalam pabrik dan mengembalikannya. layanan: Layanan Anda hanya memiliki fungsi standar yang menggunakan kata kunci ini untuk mendefinisikan fungsi. penyedia: Penyedia ada $ membuat Anda mendefinisikan dan itu dapat digunakan untuk mendapatkan objek yang mengembalikan data.
Intinya, Penyedia, Pabrik, dan Layanan adalah semua Layanan. Pabrik adalah kasus khusus dari suatu Layanan ketika yang Anda butuhkan hanyalah fungsi $ get (), memungkinkan Anda untuk menulisnya dengan kode yang lebih sedikit.
Perbedaan utama antara Layanan, Pabrik, dan Penyedia adalah kompleksitasnya. Layanan adalah bentuk paling sederhana, Pabrik sedikit lebih kuat, dan Penyedia dapat dikonfigurasi saat runtime.
Berikut ini adalah ringkasan kapan harus menggunakan masing-masing:
Pabrik : Nilai yang Anda berikan perlu dihitung berdasarkan data lain.
Layanan : Anda mengembalikan objek dengan metode.
Penyedia : Anda ingin dapat mengkonfigurasi, selama fase konfigurasi, objek yang akan dibuat sebelum dibuat. Gunakan Penyedia sebagian besar dalam konfigurasi aplikasi, sebelum aplikasi sepenuhnya diinisialisasi.
erm. Nilai, Pabrik, Layanan, dan Konstan - hanyalah gula sintaksis di atas resep penyedia. Dokumen Angularjs - penyedia
Sudarshan_SMD
ya saya setuju, sekarang dengan sudut 4 kita tidak memiliki sakit kepala ini lagi
eGhoul
4
1.Layanan adalah objek tunggal yang dibuat saat diperlukan dan tidak pernah dibersihkan hingga akhir siklus hidup aplikasi (saat browser ditutup). Pengendali dihancurkan dan dibersihkan ketika mereka tidak lagi diperlukan.
2. Cara termudah untuk membuat layanan adalah dengan menggunakan metode factory (). Metode factory () memungkinkan kita untuk mendefinisikan layanan dengan mengembalikan objek yang berisi fungsi layanan dan data layanan. Fungsi definisi layanan adalah tempat kami menempatkan layanan injeksi kami, seperti $ http dan $ q. Ex:
Metode service (), di sisi lain memungkinkan kita untuk membuat layanan dengan mendefinisikan fungsi konstruktor. Kita dapat menggunakan objek prototipikal untuk mendefinisikan layanan kami, bukan objek javascript mentah. Mirip dengan metode factory (), kami juga akan mengatur injeksi dalam definisi fungsi.
Cara tingkat terendah untuk membuat layanan adalah dengan menggunakan metode menyediakan (). Ini adalah satu-satunya cara untuk membuat layanan yang dapat kita konfigurasi menggunakan fungsi .config (). Tidak seperti metode sebelumnya, kami akan menetapkan injeksi dalam definisi fungsi yang didefinisikan. $ Get () ini.
Gula sintaksis adalah perbedaannya . Hanya penyedia yang dibutuhkan. Atau dengan kata lain hanya provider yang bersudut nyata, semua yang lain diturunkan (untuk mengurangi kode). Ada versi sederhana juga, yang disebut Value () yang mengembalikan nilai saja, tidak ada perhitungan atau fungsi. Bahkan Nilai diperoleh dari penyedia!
Jadi mengapa komplikasi seperti itu, mengapa kita tidak bisa menggunakan penyedia saja dan melupakan yang lainnya? Seharusnya membantu kita menulis kode dengan mudah dan berkomunikasi dengan lebih baik. Dan balasan toungue-in-pipi akan, semakin kompleks itu semakin baik penjualan kerangka kerja akan.
Penyedia yang dapat mengembalikan nilai = Nilai
Penyedia yang dapat langsung membuat dan mengembalikan = Pabrik (+ Nilai)
Penyedia yang dapat instantiate + melakukan sesuatu = Layanan (+ Pabrik, + Nilai)
Penyedia = harus mengandung properti yang disebut $ get (+ Factory, + Service, + Value)
Injeksi sudut memberi kita petunjuk pertama dalam mencapai kesimpulan ini.
"$ injector digunakan untuk mengambil instance objek sebagaimana didefinisikan oleh penyedia " bukan layanan, bukan pabrik tetapi penyedia.
Dan jawaban yang lebih baik adalah: "Layanan Angular dibuat oleh pabrik layanan. Pabrik-pabrik layanan ini adalah fungsi yang, pada gilirannya, diciptakan oleh penyedia layanan. Penyedia layanan adalah fungsi konstruktor. Ketika instantiated mereka harus mengandung properti disebut $ get, yang memegang fungsi pabrik layanan. "
Jadi penyedia utama dan injektor dan semua akan jatuh pada tempatnya :). Dan itu menjadi menarik dalam Script ketika $ get dapat diimplementasikan dalam penyedia dengan mewarisi dari IServiceProvider.
service.factory
. Tidak ingin memperumit masalah ini lebih lanjut.services
,factories
danproviders
bekerja.Jawaban:
Dari milis AngularJS saya mendapat utas luar biasa yang menjelaskan layanan vs pabrik vs penyedia dan penggunaan injeksi mereka. Kompilasi jawaban:
Jasa
Sintaks:
module.service( 'serviceName', function );
Hasil: Saat mendeklarasikan serviceName sebagai argumen yang dapat diinjeksi, Anda akan diberikan instance dari fungsi tersebut. Dengan kata lain
new FunctionYouPassedToService()
.Pabrik
Sintaks:
module.factory( 'factoryName', function );
Hasil: Ketika mendeklarasikan factoryName sebagai argumen injeksi, Anda akan diberikan nilai yang dikembalikan dengan memohon referensi fungsi yang diteruskan ke module.factory .
Penyedia
Sintaks:
module.provider( 'providerName', function );
Hasil: Saat mendeklarasikan providerName sebagai argumen yang dapat diinjeksi, Anda akan diberikan
(new ProviderFunction()).$get()
. Fungsi konstruktor adalah instantiated sebelum metode $ get dipanggil -ProviderFunction
adalah referensi fungsi yang diteruskan ke module.provider.Penyedia memiliki keuntungan bahwa mereka dapat dikonfigurasi selama fase konfigurasi modul.
Lihat di sini untuk kode yang disediakan.
Berikut ini penjelasan lebih lanjut dari Misko:
Dalam hal ini injektor hanya mengembalikan nilai apa adanya. Tetapi bagaimana jika Anda ingin menghitung nilainya? Kemudian gunakan pabrik
Begitu
factory
adalah fungsi yang bertanggung jawab untuk menciptakan nilai. Perhatikan bahwa fungsi pabrik dapat meminta dependensi lainnya.Tetapi bagaimana jika Anda ingin menjadi lebih OO dan memiliki kelas yang disebut Greeter?
Maka untuk instantiate Anda harus menulis
Lalu kita bisa meminta 'penyapa' di controller seperti ini
Tapi itu terlalu bertele-tele. Cara yang lebih singkat untuk menulis ini adalah
provider.service('greeter', Greeter);
Tetapi bagaimana jika kita ingin mengkonfigurasi
Greeter
kelas sebelum injeksi? Lalu kita bisa menulisMaka kita bisa melakukan ini:
Sebagai catatan,
service
,factory
, danvalue
semuanya berasal dari penyedia.sumber
toEqual
dangreeter.Greet
apa. Mengapa tidak menggunakan sesuatu yang sedikit lebih nyata dan bisa dihubungkan?Demo JS Fiddle
Contoh "Hello world" dengan
factory
/service
/provider
:sumber
this
mengubah konteks dalam$get
fungsi? - Anda tidak lagi merujuk ke penyedia instantiated dalam fungsi itu.this
sebenarnya tidak mengubah konteks, karena apa yang dipanggil adalahnew Provider()
$ get (), di manaProvider
fungsi diteruskanapp.provider
. Maksudnya dikatakan$get()
dipanggil sebagai metode pada konstruksiProvider
, jadithis
akan merujukProvider
seperti contoh yang disarankan.Unknown provider: helloWorldProvider <- helloWorld
ketika menjalankan ini secara lokal? Mengomentari itu, kesalahan yang sama untuk 2 contoh lainnya. Apakah ada konfigurasi penyedia tersembunyi? (Angular 1.0.8) - Ditemukan: stackoverflow.com/questions/12339272/…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 , AngularJS 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.
3) Penyedia adalah satu-satunya layanan yang dapat Anda gunakan untuk fungsi .config () Anda. Gunakan penyedia ketika Anda ingin memberikan konfigurasi modul-lebar untuk objek layanan Anda sebelum membuatnya tersedia.
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' dapat langsung digunakan di dalam pengontrol mana pun kita melewatkan '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 AngularJS, saya sangat merekomendasikan melakukan penyelaman mendalam pada mereka.
Di bawah setArtist menerima artis dan memungkinkan Anda untuk mengatur artis. getArtist mengembalikan artis. callItunes first calls 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 dengan 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' (Ini adalah praktik pengkodean yang baik). 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 secara keseluruhan 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 kata kunci 'baru' sebenarnya dalam JavaScript, membuat Layanan di AngularJS harus lebih mudah dimengerti.
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, setelah Anda benar-benar memahami apa yang 'baru' lakukan, Layanan hampir identik dengan pabrik di AngularJS.
3) Penyedia
Hal terbesar yang harus diingat tentang Penyedia adalah mereka satu-satunya layanan yang dapat Anda masuki ke bagian app.config dari aplikasi Anda. Ini sangat penting jika Anda perlu mengubah sebagian dari objek layanan Anda sebelum tersedia di tempat lain di aplikasi Anda. Meskipun sangat mirip dengan Layanan / Pabrik, ada beberapa perbedaan yang akan kita bahas.
Pertama, kami mengatur Penyedia kami dengan cara yang sama seperti yang kami lakukan dengan Layanan dan Pabrik kami. Variabel di bawah ini adalah fungsi 'pribadi' dan penolong kami.
* Lagi-lagi jika ada bagian dari kode di atas yang membingungkan, periksa bagian Pabrik di mana saya menjelaskan apa yang dilakukannya lebih detail.
Anda dapat menganggap Penyedia memiliki tiga bagian. Bagian pertama adalah variabel / fungsi 'pribadi' yang akan dimodifikasi / ditetapkan nanti (ditampilkan di atas). Bagian kedua adalah variabel / fungsi yang akan tersedia di fungsi app.config Anda dan karena itu tersedia untuk diubah sebelum tersedia di tempat lain (juga ditunjukkan di atas). Penting untuk dicatat bahwa variabel-variabel tersebut harus dilampirkan pada kata kunci 'ini'. Dalam contoh kita, hanya 'thingFromConfig' yang akan tersedia untuk diubah di app.config. Bagian ketiga (diperlihatkan di bawah) adalah semua variabel / fungsi yang akan tersedia di controller Anda ketika Anda memasukkan layanan 'myProvider' ke controller spesifik itu.
Saat membuat layanan dengan Penyedia, satu-satunya properti / metode yang akan tersedia di controller Anda adalah properti / metode yang dikembalikan dari fungsi $ get (). Kode di bawah ini menempatkan $ get pada 'this' (yang kita tahu pada akhirnya akan dikembalikan dari fungsi itu). Sekarang, fungsi $ get mengembalikan semua metode / properti yang kita inginkan tersedia di controller. Ini contoh kode.
Sekarang kode Penyedia lengkap terlihat seperti ini
Sekarang sama seperti di pabrik dan Layanan kami, setArtist, getArtist, dan callItunes akan tersedia di mana pun pengendali tempat kami memberikan myProvider. Inilah pengontrol myProvider (yang hampir persis sama dengan pengontrol pabrik / Layanan kami).
Seperti yang disebutkan sebelumnya, inti dari menciptakan layanan dengan Penyedia adalah untuk dapat mengubah beberapa variabel melalui fungsi app.config sebelum objek terakhir diteruskan ke sisa aplikasi. Mari kita lihat contohnya.
Sekarang Anda dapat melihat bagaimana 'thingFromConfig' sebagai string kosong di penyedia kami, tetapi ketika itu muncul di DOM, itu akan menjadi 'Kalimat ini telah ditetapkan ...'.
sumber
Semua Layanan adalah lajang ; mereka akan instantiated sekali per aplikasi. Mereka bisa dari jenis apa pun , apakah itu primitif, objek literal, fungsi, atau bahkan turunan dari jenis kustom.
The
value
,factory
,service
,constant
, danprovider
metode yang semua penyedia. Mereka mengajarkan Injector bagaimana membuat Instansiasi Layanan.decorator
.sumber
Memahami Pabrik, Layanan, dan Penyedia AngularJS
Semua ini digunakan untuk berbagi objek singleton yang dapat digunakan kembali. Ini membantu untuk membagikan kode yang dapat digunakan kembali di aplikasi Anda / berbagai komponen / modul.
Pabrik
Pabrik adalah fungsi tempat Anda dapat memanipulasi / menambahkan logika sebelum membuat objek, lalu objek yang baru dibuat akan dikembalikan.
Pemakaian
Ini bisa jadi hanya kumpulan fungsi seperti kelas. Oleh karena itu, ini dapat dipakai di pengontrol yang berbeda ketika Anda menyuntikkannya di dalam fungsi pengontrol / pabrik / direktif Anda. Ini dipakai hanya sekali per aplikasi.
Layanan
Cukup sambil melihat layanan berpikir tentang prototipe array. Layanan adalah fungsi yang membuat objek baru menggunakan kata kunci 'baru'. Anda dapat menambahkan properti dan fungsi ke objek layanan dengan menggunakan
this
kata kunci. Tidak seperti pabrik, itu tidak mengembalikan apa pun (itu mengembalikan objek yang berisi metode / properti).Pemakaian
Gunakan saat Anda perlu membagikan satu objek di seluruh aplikasi. Misalnya, rincian pengguna yang diautentikasi, metode / data yang dapat dibagikan, fungsi Utilitas dll.
Pemberi
Penyedia digunakan untuk membuat objek layanan yang dapat dikonfigurasi. Anda dapat mengonfigurasi pengaturan layanan dari fungsi konfigurasi. Ini mengembalikan nilai dengan menggunakan
$get()
fungsi. The$get
Fungsi dijalankan pada fase run di sudut.Pemakaian
Ketika Anda perlu memberikan konfigurasi bijaksana untuk objek layanan Anda sebelum membuatnya tersedia, misalnya. misalkan Anda ingin mengatur URL API Anda berdasarkan Lingkungan Anda seperti
dev
,stage
atauprod
Semoga ini telah menjernihkan pemahaman Anda tentang Pabrik, Layanan, dan Penyedia .
sumber
only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications
, jadi sepertinya tidak mungkin, kan?Bagi saya, wahyu datang ketika saya menyadari bahwa mereka semua bekerja dengan cara yang sama: dengan menjalankan sesuatu sekali , menyimpan nilai yang mereka dapatkan, dan kemudian batuk nilai tersimpan yang sama ketika direferensikan melalui injeksi ketergantungan .
Katakanlah kita memiliki:
Perbedaan antara ketiganya adalah:
a
Nilai yang disimpan berasal dari menjalankanfn
.b
Nilai yang disimpan berasal darinew
ingfn
.c
Nilai yang disimpan berasal dari pertama mendapatkan instance dengannew
ingfn
, dan kemudian menjalankan$get
metode instance.Yang berarti ada sesuatu seperti objek cache di dalam AngularJS, yang nilainya setiap injeksi hanya diberikan satu kali, ketika mereka telah disuntikkan pertama kali, dan di mana:
Inilah sebabnya kami menggunakan
this
dalam layanan, dan mendefinisikanthis.$get
penyedia dalam.sumber
factory
s. Satu-satunya alasanservice
yang ada adalah bahasa seperti CoffeeScript, TypeScript, ES6 dll. Sehingga Anda dapat menggunakan sintaks kelasnya. Andaprovider
hanya perlu jika modul Anda digunakan di beberapa aplikasi dengan pengaturan yang berbeda dengan menggunakanapp.config()
. Jika layanan Anda adalah singleton murni atau mampu membuat instance sesuatu hanya tergantung pada implementasi Anda.Layanan vs penyedia vs pabrik:
Saya mencoba membuatnya tetap sederhana. Ini semua tentang konsep dasar JavaScript.
Pertama-tama, mari kita bicara tentang layanan di AngularJS!
Apa itu Layanan: Di AngularJS, Layanantidak lain adalah objek JavaScript tunggal yang dapat menyimpan beberapa metode atau properti yang berguna. Objek tunggal ini dibuat per ngApp (aplikasi Angular) dan dibagi di antara semua pengontrol dalam aplikasi saat ini. Ketika Angularjs instantiate objek layanan, itu mendaftarkan objek layanan ini dengan nama layanan yang unik. Jadi setiap kali ketika kita membutuhkan instance layanan, Angular mencari registri untuk nama layanan ini, dan mengembalikan referensi ke objek layanan. Sehingga kita dapat memanggil metode, mengakses properti dll pada objek layanan. Anda mungkin memiliki pertanyaan apakah Anda juga dapat menempatkan properti, metode pada objek lingkup pengontrol! Jadi mengapa Anda membutuhkan objek layanan? Jawabannya adalah: layanan dibagi di antara beberapa lingkup pengontrol. Jika Anda meletakkan beberapa properti / metode dalam objek lingkup pengontrol, itu akan tersedia untuk lingkup saat ini saja.
Jadi jika ada tiga ruang lingkup pengontrol, misalkan pengontrolA, pengontrolB dan pengontrolC, semua akan berbagi layanan yang sama.
Bagaimana cara membuat layanan?
AngularJS menyediakan berbagai metode untuk mendaftarkan layanan. Di sini kita akan berkonsentrasi pada tiga metode factory (..), service (..), provider (..);
Gunakan tautan ini untuk referensi kode
Fungsi pabrik:
Kita dapat mendefinisikan fungsi pabrik seperti di bawah ini.
AngularJS menyediakan metode 'factory (' serviceName ', fnFactory)' yang mengambil dua parameter, serviceName dan fungsi JavaScript. Angular membuat instance layanan dengan menjalankan fungsi fnFactory () seperti di bawah ini.
Fungsi yang diteruskan dapat mendefinisikan objek dan mengembalikan objek itu. AngularJS hanya menyimpan referensi objek ini ke variabel yang diteruskan sebagai argumen pertama. Apa pun yang dikembalikan dari fnFactory akan terikat ke serviceInstance. Alih-alih mengembalikan objek, kita juga dapat mengembalikan fungsi, nilai, dll. Apapun yang akan kita kembalikan, akan tersedia untuk instance layanan.
Contoh:
Fungsi layanan:
Ini cara lain, kita bisa mendaftarkan layanan. Satu-satunya perbedaan adalah cara AngularJS mencoba untuk instantiate objek layanan. Kali ini sudut menggunakan kata kunci 'baru' dan memanggil fungsi konstruktor seperti di bawah ini.
Dalam fungsi konstruktor kita dapat menggunakan kata kunci 'ini' untuk menambahkan properti / metode ke objek layanan. contoh:
Fungsi penyedia:
Fungsi Provider () adalah cara lain untuk membuat layanan. Biarkan kami tertarik untuk membuat layanan yang hanya menampilkan beberapa pesan ucapan kepada pengguna. Tetapi kami juga ingin menyediakan fungsionalitas sehingga pengguna dapat mengatur pesan ucapan mereka sendiri. Dalam istilah teknis kami ingin membuat layanan yang dapat dikonfigurasi. Bagaimana kita bisa melakukan ini? Harus ada cara, sehingga aplikasi dapat mengirimkan pesan ucapan khusus mereka dan Angular akan membuatnya tersedia untuk fungsi pabrik / konstruktor yang membuat instance layanan kami. Dalam hal ini penyedia fungsi () melakukan pekerjaan. menggunakan fungsi provider () kita dapat membuat layanan yang dapat dikonfigurasi.
Kami dapat membuat layanan yang dapat dikonfigurasi menggunakan sintaksis penyedia seperti yang diberikan di bawah ini.
Bagaimana cara kerja sintaksis penyedia secara internal?
1.Provider object dibuat menggunakan fungsi konstruktor yang kami definisikan dalam fungsi provider kami.
2.Fungsi yang kami lewati di app.config (), dijalankan. Ini disebut tahap konfigurasi, dan di sini kami memiliki kesempatan untuk menyesuaikan layanan kami.
3. Akhirnya layanan dibuat dengan memanggil metode $ get dari serviceProvider.
Kode sampel untuk membuat layanan menggunakan sintaks menyediakan:
Demo yang Bekerja
Ringkasan:
Pabrik menggunakan fungsi pabrik yang mengembalikan instance layanan. serviceInstance = fnFactory ();
Layanan menggunakan fungsi konstruktor dan Angular memanggil fungsi konstruktor ini menggunakan kata kunci 'baru' untuk membuat turunan layanan. serviceInstance = new fnServiceConstructor ();
Penyedia mendefinisikan fungsi providerConstructor, fungsi providerConstructor ini mendefinisikan fungsi pabrik $ get . Panggilan sudut $ get () untuk membuat objek layanan. Sintaks penyedia memiliki keuntungan tambahan untuk mengkonfigurasi objek layanan sebelum instantiated. serviceInstance = $ get ();
sumber
Seperti yang ditunjukkan oleh beberapa orang di sini dengan benar pabrik, penyedia, layanan, dan bahkan nilai dan konstan adalah versi dari hal yang sama. Anda dapat membedah yang lebih umum
provider
menjadi semuanya. Seperti itu:Inilah artikel dari gambar ini:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
sumber
Pabrik
Anda memberi AngularJS fungsi, AngularJS akan melakukan cache dan menyuntikkan nilai kembali ketika pabrik diminta.
Contoh:
Pemakaian:
Layanan
Anda memberi AngularJS fungsi, AngularJS akan memanggil baru untuk membuat instance. Ini adalah contoh yang dibuat AngularJS yang akan di-cache dan disuntikkan ketika layanan diminta. Karena baru digunakan untuk membuat instantiate layanan, kata kunci ini valid dan merujuk ke instance.
Contoh:
Pemakaian:
Pemberi
Anda memberi AngularJS fungsi, dan AngularJS akan memanggil
$get
fungsinya. Ini adalah nilai balik dari$get
fungsi yang akan di-cache dan disuntikkan ketika layanan diminta.Penyedia memungkinkan Anda untuk mengkonfigurasi penyedia sebelum AngularJS memanggil
$get
metode untuk mendapatkan injeksi.Contoh:
Penggunaan (sebagai suntikan pada pengontrol)
Penggunaan (mengkonfigurasi penyedia sebelum
$get
dipanggil untuk membuat injeksi)sumber
Saya perhatikan sesuatu yang menarik ketika bermain-main dengan penyedia.
Visibilitas dari suntikan berbeda untuk penyedia daripada untuk layanan dan pabrik. Jika Anda menyatakan AngularJS "konstan" (misalnya,
myApp.constant('a', 'Robert');
), Anda dapat menyuntikkannya ke layanan, pabrik, dan penyedia.Tetapi jika Anda mendeklarasikan "nilai" AngularJS (misalnya.,
myApp.value('b', {name: 'Jones'});
), Anda dapat menyuntikkannya ke layanan dan pabrik, tetapi BUKAN ke dalam fungsi pembuatan penyedia. Namun, Anda dapat menyuntikkannya ke$get
fungsi yang Anda tetapkan untuk penyedia Anda. Ini disebutkan dalam dokumentasi AngularJS, tetapi mudah untuk dilewatkan. Anda dapat menemukannya di halaman% sediakan di bagian nilai dan metode konstan.http://jsfiddle.net/R2Frv/1/
sumber
Ini adalah bagian yang sangat membingungkan bagi pemula dan saya telah mencoba menjelaskannya dengan kata-kata yang mudah
Layanan AngularJS: digunakan untuk berbagi fungsi utilitas dengan referensi layanan di controller. Layanan bersifat tunggal sehingga untuk satu layanan hanya satu instance yang dibuat di browser dan referensi yang sama digunakan di seluruh halaman.
Dalam layanan, kami membuat nama fungsi sebagai properti dengan objek ini .
AngularJS Factory: tujuan Factory juga sama dengan Service namun dalam hal ini kami membuat objek baru dan menambahkan fungsi sebagai properti dari objek ini dan pada akhirnya kami mengembalikan objek ini.
AngularJS Provider: tujuan ini sekali lagi sama namun Provider memberikan output fungsi $ get.
Menentukan dan menggunakan Layanan, Pabrik, dan Penyedia dijelaskan di http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider
sumber
Bagi saya cara terbaik dan paling sederhana untuk memahami perbedaannya adalah:
Bagaimana AngularJS instantiate komponen tertentu (disederhanakan):
Jadi, untuk layanan, yang menjadi komponen AngularJS adalah instance objek dari kelas yang diwakili oleh fungsi deklarasi layanan. Untuk pabrik, itu adalah hasil yang dikembalikan dari fungsi deklarasi pabrik. Pabrik mungkin berperilaku sama dengan layanan:
Cara berpikir paling sederhana adalah yang berikut:
Contoh 'kelas' pabrik diberikan dalam komentar di sekitar, serta perbedaan penyedia.
sumber
new MyService()
atau sesuatu :)Klarifikasi saya tentang masalah ini:
Pada dasarnya semua jenis yang disebutkan (layanan, pabrik, penyedia, dll.) Hanya membuat dan mengkonfigurasi variabel global (yang tentu saja global ke seluruh aplikasi), sama seperti variabel global kuno itu.
Sementara variabel global tidak direkomendasikan, penggunaan nyata dari variabel global ini adalah untuk memberikan injeksi ketergantungan , dengan meneruskan variabel ke pengontrol yang relevan.
Ada banyak tingkat komplikasi dalam menciptakan nilai untuk "variabel global":
Ini mendefinisikan konstanta aktual yang tidak boleh dimodifikasi selama keseluruhan aplikasi, seperti halnya konstanta dalam bahasa lain (sesuatu yang tidak dimiliki JavaScript).
Ini adalah nilai atau objek yang dapat dimodifikasi, dan berfungsi sebagai beberapa variabel global, yang bahkan dapat disuntikkan ketika membuat layanan atau pabrik lain (lihat lebih lanjut tentang ini). Namun, itu harus berupa " nilai literal ", yang berarti bahwa seseorang harus menuliskan nilai aktual, dan tidak dapat menggunakan perhitungan atau logika pemrograman apa pun (dengan kata lain 39 atau myText atau {prop: "value"} tidak apa-apa, tetapi 2 +2 tidak).
Nilai yang lebih umum, yang memungkinkan untuk segera dihitung. Ia bekerja dengan melewatkan fungsi ke AngularJS dengan logika yang diperlukan untuk menghitung nilai dan AngularJS mengeksekusi itu, dan menyimpan nilai kembali dalam variabel bernama.
Perhatikan bahwa dimungkinkan untuk mengembalikan objek (dalam hal ini akan berfungsi mirip dengan layanan ) atau fungsi (yang akan disimpan dalam variabel sebagai fungsi panggilan balik).
Suatu layanan adalah versi pabrik yang lebih sederhana yang hanya valid ketika nilainya adalah objek, dan memungkinkan untuk menulis logika apa pun secara langsung dalam fungsi (seolah-olah itu akan menjadi konstruktor), serta mendeklarasikan dan mengakses properti objek menggunakan kata kunci ini .
Tidak seperti layanan yang merupakan versi pabrik yang disederhanakan , penyedia adalah cara yang lebih kompleks, tetapi lebih fleksibel untuk menginisialisasi variabel "global", dengan fleksibilitas terbesar adalah opsi untuk menetapkan nilai dari app.config.
Ini berfungsi seperti menggunakan kombinasi layanan dan penyedia , dengan mengirimkan ke penyedia fungsi yang memiliki properti yang dideklarasikan menggunakan kata kunci ini , yang dapat digunakan dari
app.config
.Maka ia perlu memiliki fungsi $ .get terpisah yang dijalankan oleh AngularJS setelah menyetel properti di atas melalui
app.config
file, dan fungsi $ .get ini berlaku seperti pabrik. di atas, dalam nilai pengembaliannya digunakan untuk menginisialisasi variabel "global".sumber
Pemahaman saya sangat sederhana di bawah ini.
Pabrik: Anda cukup membuat objek di dalam pabrik dan mengembalikannya.
Layanan:
Anda hanya memiliki fungsi standar yang menggunakan kata kunci ini untuk mendefinisikan suatu fungsi.
Pemberi:
Ada
$get
objek yang Anda tetapkan dan dapat digunakan untuk mendapatkan objek yang mengembalikan data.sumber
Ringkasan dari dokumen Angular :
Jawaban terbaik dari SO:
https://stackoverflow.com/a/26924234/165673 (<- GOOD) https://stackoverflow.com/a/27263882/165673
https://stackoverflow.com/a/16566144/165673
sumber
Semua jawaban bagus sudah. Saya ingin menambahkan beberapa poin lagi pada Layanan dan Pabrik . Seiring dengan perbedaan antara layanan / pabrik. Dan seseorang juga dapat memiliki pertanyaan seperti:
Mari kita mulai dengan perbedaan antara Layanan dan pabrik:
Keduanya Singletons : Setiap kali Angular menemukan ini sebagai dependensi pertama kali, itu membuat contoh layanan / pabrik. Setelah instance dibuat, instance yang sama digunakan selamanya.
Dapat digunakan untuk memodelkan objek dengan perilaku : Keduanya dapat memiliki metode, variabel status internal, dan sebagainya. Meskipun cara Anda menulis kode itu akan berbeda.
Jasa:
Layanan adalah fungsi konstruktor, dan Angular akan instantiate dengan memanggil baru
yourServiceName()
. Ini berarti beberapa hal.this
.new yourServiceName(
), ia akan menerimathis
objek dengan semua properti yang Anda masukkan.Contoh Contoh:
Hati-hati dengan
this
:Karena layanan yang dibangun adalah objek, metode di dalamnya dapat merujuk ini ketika mereka dipanggil:
Anda mungkin tergoda untuk memanggil
ScoreKeeper.setScore
rantai janji, misalnya jika Anda menginisialisasi skor dengan meraihnya dari server:$http.get('/score').then(ScoreKeeper.setScore).
Masalahnya adalah iniScoreKeeper.setScore
akan dipanggil denganthis
terikatnull
dan Anda akan mendapatkan kesalahan. Cara yang lebih baik$http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper))
. Apakah Anda memilih untuk menggunakan ini dalam metode layanan Anda atau tidak, berhati-hatilah bagaimana Anda menyebutnya.Mengembalikan Nilai dari a
Service
:Karena cara kerja konstruktor JavaScript, jika Anda mengembalikan nilai kompleks
(i.e., an Object)
dari aconstructor
fungsi, pemanggil akan mendapatkan Objek itu daripada instance ini.Ini berarti bahwa Anda pada dasarnya dapat menyalin-menempelkan contoh pabrik dari bawah, ganti
factory
denganservice
, dan itu akan berhasil:Jadi ketika Angular membangun layanan Anda dengan MyService baru (), ia akan mendapatkan objek api itu alih-alih instance MyService.
Ini adalah perilaku untuk setiap nilai kompleks (objek, fungsi) tetapi tidak untuk tipe primitif.
Pabrik:
Pabrik adalah fungsi lama sederhana yang mengembalikan nilai. Nilai pengembalian adalah apa yang disuntikkan ke dalam hal-hal yang bergantung pada pabrik. Pola khas pabrik di Angular adalah mengembalikan objek dengan fungsi sebagai properti, seperti ini:
Jawaban untuk pertanyaan 1 dan 2 di atas:
sumber
Klarifikasi tambahan adalah bahwa pabrik dapat membuat fungsi / primitif, sementara layanan tidak bisa. Lihatlah jsFiddle ini berdasarkan Epokk: http://jsfiddle.net/skeller88/PxdSP/1351/ .
Pabrik mengembalikan fungsi yang dapat dipanggil:
Pabrik juga dapat mengembalikan objek dengan metode yang dapat dipanggil:
Layanan mengembalikan objek dengan metode yang dapat dipanggil:
Untuk lebih jelasnya, lihat posting yang saya tulis tentang perbedaannya: http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/
sumber
Sudah ada jawaban bagus, tapi saya hanya ingin membagikan yang ini.
Pertama-tama: Penyedia adalah cara / resep untuk membuat
service
(objek tunggal) yang seharusnya disuntikkan oleh $ injector (bagaimana AngulaJS berjalan tentang pola IoC).Dan Nilai, Pabrik, Layanan dan Konstan (4 cara) - gula sintaksis atas Penyedia cara / penerima.
Ada
Service vs Factory
bagian yang telah dibahas: https://www.youtube.com/watch?v=BLzNCkPn3aoLayanan adalah tentang
new
kata kunci sebenarnya yang seperti yang kita ketahui melakukan 4 hal:prototype
objeknyacontext
kethis
this
Dan Pabrik adalah semua tentang Pola Pabrik - berisi fungsi yang mengembalikan Objek seperti Layanan itu.
Dan video sederhana / singkat ini: mencakup juga Penyedia : https://www.youtube.com/watch?v=HvTZbQ_hUZY (di sana Anda dapat melihat bagaimana mereka beralih dari satu pabrik ke penyedia lainnya)
Resep penyedia sebagian besar digunakan dalam konfigurasi aplikasi, sebelum aplikasi sepenuhnya dimulai / diinisialisasi.
sumber
Setelah membaca semua posting ini, itu membuat saya lebih bingung .. Tapi tetap saja semua informasi berharga .. akhirnya saya menemukan tabel berikut yang akan memberikan informasi dengan perbandingan sederhana
Dan untuk pemula pahami: - Ini mungkin tidak memperbaiki use case tetapi pada level tinggi inilah yang digunakan untuk ketiganya.
Untuk skenario dasar, pabrik & Layanan berperilaku sama.
sumber
Berikut adalah beberapa kode platfile yang saya buat sebagai templat kode untuk objek pabrik di AngularjS. Saya telah menggunakan Car / CarFactory sebagai contoh untuk menggambarkan. Membuat kode implementasi sederhana di controller.
Ini adalah contoh sederhana. Saya menggunakan beberapa pustaka pihak ketiga yang mengharapkan objek "Posisi" yang mengekspos lintang dan bujur, tetapi melalui properti objek yang berbeda. Saya tidak ingin meretas kode vendor, jadi saya menyesuaikan objek "Posisi" yang saya berikan.
;
sumber
Menggunakan referensi halaman ini dan dokumentasi (yang tampaknya telah sangat meningkat sejak terakhir kali saya melihat), saya mengumpulkan demo dunia nyata (-ish) berikut ini yang menggunakan 4 dari 5 rasa penyedia; Penyedia Nilai, Konstan, Pabrik, dan peniupan penuh.
HTML:
aplikasi
Demo kerja .
sumber
Jawaban ini membahas topik / pertanyaan
bagaimana Factory, Service dan Constant - hanya gula sintaksis di atas resep penyedia?
ATAU
bagaimana pabrik, layanan dan penyedia simailar secara internal
pada dasarnya yang terjadi adalah
Ketika Anda membuatnya
factory()
menetapkan Andafunction
berikan dalam argumen kedua ke penyedia$get
dan mengembalikannya (provider(name, {$get:factoryFn })
), yang Anda dapatkan hanyalahprovider
tetapi tidak ada properti / metode selain$get
ituprovider
(artinya Anda tidak dapat mengonfigurasi ini)Kode sumber pabrik
Ketika membuatnya
service()
mengembalikan Anda memberikan pabrik () denganfunction
yang menyuntikkanconstructor
(mengembalikan instance dari konstruktor yang Anda berikan dalam layanan Anda) dan mengembalikannyaKode sumber layanan
Jadi pada dasarnya dalam kedua kasus Anda akhirnya mendapatkan penyedia $ bisa diatur untuk fungsi yang Anda berikan, tetapi Anda bisa memberikan apa pun lebih dari $ dapatkan karena Anda awalnya dapat menyediakan di provider () untuk blok konfigurasi
sumber
Saya tahu banyak jawaban yang sangat baik tetapi saya harus berbagi pengalaman saya menggunakan
1.
service
untuk sebagian besar kasus default2.
factory
digunakan untuk membuat layanan contoh khususdan menggunakan:
sumber
Agak terlambat ke pesta. Tapi saya pikir ini lebih bermanfaat bagi yang ingin belajar (atau memiliki kejelasan) tentang pengembangan Layanan Kustom JS Angular menggunakan metodologi pabrik, layanan, dan penyedia.
Saya menemukan video ini yang menjelaskan dengan jelas tentang metodologi pabrik, layanan, dan penyedia untuk mengembangkan Layanan Kustom AngularJS:
https://www.youtube.com/watch?v=oUXku28ex-M
Kode sumber: http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service
Kode yang diposting di sini disalin langsung dari sumber di atas, untuk memberi manfaat bagi pembaca.
Kode untuk layanan kustom berbasis "pabrik" adalah sebagai berikut (yang berlaku dengan versi sinkronisasi dan async bersamaan dengan memanggil layanan http):
Kode untuk metodologi "layanan" untuk Layanan Kustom (ini sangat mirip dengan 'pabrik', tetapi berbeda dari sudut pandang sintaksis):
Kode untuk metodologi "penyedia" untuk Layanan Kustom (ini diperlukan, jika Anda ingin mengembangkan layanan yang dapat dikonfigurasi):
Akhirnya UI yang bekerja dengan salah satu layanan di atas:
sumber
Untuk memperjelas beberapa hal, dari sumber AngularJS, Anda dapat melihat layanan memanggil fungsi pabrik yang kemudian memanggil fungsi penyedia:
sumber
Mari kita bahas tiga cara menangani logika bisnis di AngularJS dengan cara sederhana: ( Terinspirasi oleh kursus Coursera AngularJS Yaakov )
LAYANAN :
Sintaksis:
app.js
index.html
Fitur Layanan:
PABRIK
Pertama mari kita lihat sintaks:
app.js :
Sekarang menggunakan dua di atas di controller:
Fitur pabrik:
.service()
Metode adalah pabrik yang selalu menghasilkan jenis yang sama dari layanan, yang tunggal, dan tanpa cara mudah untuk mengkonfigurasi perilaku itu. Itu.service()
metode biasanya digunakan sebagai jalan pintas untuk sesuatu yang tidak memerlukan apapun konfigurasi.PEMBERI
Mari kita lihat Sintaks lebih dulu:
Fitur Penyedia:
.service
atau.factory
metode.$get
adalah fungsi yang secara langsung dilampirkan ke instance penyedia. Fungsi itu adalah fungsi pabrik . Dengan kata lain, itu hanya seperti salah satu yang kita gunakan untuk memberikan kepada.factory
metode. Dalam fungsi itu, kami membuat layanan kami sendiri. Properti ini$get
, itulah fungsi, yang membuat penyedia menjadi penyedia . AngularJS mengharapkan penyedia memiliki properti $ get yang nilainya merupakan fungsi yang akan diperlakukan Angular sebagai fungsi pabrik. Tetapi apa yang membuat seluruh pengaturan penyedia ini sangat istimewa, adalah kenyataan bahwa kami dapat menyediakan beberapaconfig
objek di dalam penyedia layanan, dan yang biasanya disertai dengan default yang nantinya dapat kami timpa dalam langkah tersebut, di mana kami dapat mengonfigurasi seluruh aplikasi.sumber
Pabrik: Pabrik Anda benar-benar membuat objek di dalam pabrik dan mengembalikannya.
layanan: Layanan Anda hanya memiliki fungsi standar yang menggunakan kata kunci ini untuk mendefinisikan fungsi.
penyedia: Penyedia ada $ membuat Anda mendefinisikan dan itu dapat digunakan untuk mendapatkan objek yang mengembalikan data.
sumber
Intinya, Penyedia, Pabrik, dan Layanan adalah semua Layanan. Pabrik adalah kasus khusus dari suatu Layanan ketika yang Anda butuhkan hanyalah fungsi $ get (), memungkinkan Anda untuk menulisnya dengan kode yang lebih sedikit.
Perbedaan utama antara Layanan, Pabrik, dan Penyedia adalah kompleksitasnya. Layanan adalah bentuk paling sederhana, Pabrik sedikit lebih kuat, dan Penyedia dapat dikonfigurasi saat runtime.
Berikut ini adalah ringkasan kapan harus menggunakan masing-masing:
Pabrik : Nilai yang Anda berikan perlu dihitung berdasarkan data lain.
Layanan : Anda mengembalikan objek dengan metode.
Penyedia : Anda ingin dapat mengkonfigurasi, selama fase konfigurasi, objek yang akan dibuat sebelum dibuat. Gunakan Penyedia sebagian besar dalam konfigurasi aplikasi, sebelum aplikasi sepenuhnya diinisialisasi.
sumber
1.Layanan adalah objek tunggal yang dibuat saat diperlukan dan tidak pernah dibersihkan hingga akhir siklus hidup aplikasi (saat browser ditutup). Pengendali dihancurkan dan dibersihkan ketika mereka tidak lagi diperlukan.
2. Cara termudah untuk membuat layanan adalah dengan menggunakan metode factory (). Metode factory () memungkinkan kita untuk mendefinisikan layanan dengan mengembalikan objek yang berisi fungsi layanan dan data layanan. Fungsi definisi layanan adalah tempat kami menempatkan layanan injeksi kami, seperti $ http dan $ q. Ex:
Menggunakan pabrik () di aplikasi kami
Sangat mudah untuk menggunakan pabrik di aplikasi kita karena kita bisa menyuntikkannya di mana kita membutuhkannya saat dijalankan.
sumber
Gula sintaksis adalah perbedaannya . Hanya penyedia yang dibutuhkan. Atau dengan kata lain hanya provider yang bersudut nyata, semua yang lain diturunkan (untuk mengurangi kode). Ada versi sederhana juga, yang disebut Value () yang mengembalikan nilai saja, tidak ada perhitungan atau fungsi. Bahkan Nilai diperoleh dari penyedia!
Jadi mengapa komplikasi seperti itu, mengapa kita tidak bisa menggunakan penyedia saja dan melupakan yang lainnya? Seharusnya membantu kita menulis kode dengan mudah dan berkomunikasi dengan lebih baik. Dan balasan toungue-in-pipi akan, semakin kompleks itu semakin baik penjualan kerangka kerja akan.
Injeksi sudut memberi kita petunjuk pertama dalam mencapai kesimpulan ini.
"$ injector digunakan untuk mengambil instance objek sebagaimana didefinisikan oleh penyedia " bukan layanan, bukan pabrik tetapi penyedia.
Dan jawaban yang lebih baik adalah: "Layanan Angular dibuat oleh pabrik layanan. Pabrik-pabrik layanan ini adalah fungsi yang, pada gilirannya, diciptakan oleh penyedia layanan. Penyedia layanan adalah fungsi konstruktor. Ketika instantiated mereka harus mengandung properti disebut $ get, yang memegang fungsi pabrik layanan. "
Jadi penyedia utama dan injektor dan semua akan jatuh pada tempatnya :). Dan itu menjadi menarik dalam Script ketika $ get dapat diimplementasikan dalam penyedia dengan mewarisi dari IServiceProvider.
sumber