Bir arasındaki farklar nelerdir Service
, Provider
ve Factory
angularjs içinde?
service.factory
. Bu konuyu daha da karmaşıklaştırmak istemiyordu.
Bir arasındaki farklar nelerdir Service
, Provider
ve Factory
angularjs içinde?
service.factory
. Bu konuyu daha da karmaşıklaştırmak istemiyordu.
Yanıtlar:
AngularJS posta listesinden , fabrikaya karşı servis sağlayıcıya ve bunların enjeksiyon kullanımına ilişkin inanılmaz bir iş parçacığı aldım . Cevapların derlenmesi:
Sözdizimi: module.service( 'serviceName', function );
Sonuç: serviceName öğesini enjekte edilebilir bir bağımsız değişken olarak bildirirken , işlevin bir örneğini alırsınız. Başka bir deyişle new FunctionYouPassedToService()
.
Sözdizimi: module.factory( 'factoryName', function );
Sonuç: factoryName öğesini enjekte edilebilir bir bağımsız değişken olarak bildirirken, module.factory öğesine iletilen işlev başvurusunu çağırarak döndürülen değer size sağlanacaktır .
Sözdizimi: module.provider( 'providerName', function );
Sonuç: Sağlayıcı adını enjekte edilebilir bir argüman olarak bildirirken size sağlanacaktır (new ProviderFunction()).$get()
. Yapıcı işlevi, $ get yöntemi çağrılmadan önce başlatılır - ProviderFunction
module.provider öğesine iletilen işlev başvurusudur.
Sağlayıcılar modül yapılandırma aşamasında yapılandırılabilme avantajına sahiptir.
Sağlanan kod için buraya bakın .
İşte Misko'nun daha fazla açıklaması:
provide.value('a', 123);
function Controller(a) {
expect(a).toEqual(123);
}
Bu durumda, enjektör değeri olduğu gibi döndürür. Ama ya değeri hesaplamak istiyorsan? Sonra bir fabrika kullanın
provide.factory('b', function(a) {
return a*2;
});
function Controller(b) {
expect(b).toEqual(246);
}
Bu factory
, değeri yaratmaktan sorumlu bir işlevdir. Fabrika fonksiyonunun diğer bağımlılıkları isteyebileceğine dikkat edin.
Peki ya daha çok OO olmak ve Greeter adında bir sınıfa sahip olmak istiyorsanız?
function Greeter(a) {
this.greet = function() {
return 'Hello ' + a;
}
}
Daha sonra, yazmak için
provide.factory('greeter', function(a) {
return new Greeter(a);
});
Sonra kontrolörde böyle 'selam' isteyebiliriz
function Controller(greeter) {
expect(greeter instanceof Greeter).toBe(true);
expect(greeter.greet()).toEqual('Hello 123');
}
Ama bu çok garip. Bunu yazmanın daha kısa bir yoluprovider.service('greeter', Greeter);
Peki ya Greeter
enjeksiyondan önce sınıfı yapılandırmak isteseydik ? Sonra yazabiliriz
provide.provider('greeter2', function() {
var salutation = 'Hello';
this.setSalutation = function(s) {
salutation = s;
}
function Greeter(a) {
this.greet = function() {
return salutation + ' ' + a;
}
}
this.$get = function(a) {
return new Greeter(a);
};
});
Sonra bunu yapabiliriz:
angular.module('abc', []).config(function(greeter2Provider) {
greeter2Provider.setSalutation('Halo');
});
function Controller(greeter2) {
expect(greeter2.greet()).toEqual('Halo 123');
}
Bir not olarak, service
, factory
ve value
her sağlayıcıdan elde edilir.
provider.service = function(name, Class) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.instantiate(Class);
};
});
}
provider.factory = function(name, factory) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.invoke(factory);
};
});
}
provider.value = function(name, value) {
provider.factory(name, function() {
return value;
});
};
toEqual
ve ne olduğunu anlamaya çalışırken kayboluyorum greeter.Greet
. Neden biraz daha gerçek ve ilişkilendirilebilir bir şey kullanmıyorsunuz?
factory
/ service
/ İle "Merhaba dünya" örneği 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');
});
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
$scope.hellos = [
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
{{hellos}}
</div>
</body>
this
bağlamı değiştirmez $get
mi? - artık bu işlevdeki örnek sağlayıcıya başvurmuyorsunuz.
this
aslında bağlamı değiştirmez, çünkü çağrılan şey new Provider()
. $ Get (), burada Provider
fonksiyonun geçildiği yerdir app.provider
. Yani $get()
bu inşa edilmiş bir yöntem olarak adlandırılmaktadır Provider
, bu yüzden örnekte belirtildiği gibi this
atıfta bulunacaktır Provider
.
Unknown provider: helloWorldProvider <- helloWorld
yerel olarak çalıştırırken neden alıyorum ? Yorumlamak, diğer 2 örnek için aynı hata. Gizli sağlayıcı yapılandırması var mı? (Açısal 1.0.8) - Bulunan: stackoverflow.com/questions/12339272/…
TL; DR
1) Bir Fabrika kullanırken bir nesne yaratırsınız, ona özellikler ekler ve sonra aynı nesneyi döndürürsünüz. Bu fabrikayı denetleyicinize ilettiğinizde, nesne üzerindeki bu özellikler artık o denetleyicide fabrikanız aracılığıyla kullanılabilir.
app.controller(‘myFactoryCtrl’, function($scope, myFactory){
$scope.artist = myFactory.getArtist();
});
app.factory(‘myFactory’, function(){
var _artist = ‘Shakira’;
var service = {};
service.getArtist = function(){
return _artist;
}
return service;
});
2) Hizmet'i kullanırken , AngularJS 'yeni' anahtar kelimesi ile bunları sahne arkasında başlatır. Bu nedenle, 'this' öğesine özellikler eklersiniz ve hizmet 'this' öğesini döndürür. Hizmeti denetleyicinize ilettiğinizde, 'bu' öğesindeki özellikler artık hizmetiniz üzerinden bu denetleyicide kullanılabilir.
app.controller(‘myServiceCtrl’, function($scope, myService){
$scope.artist = myService.getArtist();
});
app.service(‘myService’, function(){
var _artist = ‘Nelly’;
this.getArtist = function(){
return _artist;
}
});
3) Sağlayıcılar .config () işlevinize iletebileceğiniz tek hizmettir. Hizmet nesneniz için kullanılabilir hale getirmeden önce modül çapında yapılandırma sağlamak istediğinizde bir sağlayıcı kullanın.
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 set in config’;
});
TL olmayan; DR
1) Fabrika
Fabrikaları bir hizmet oluşturmak ve yapılandırmak için en popüler yoldur. TL'nin söylediğinden çok daha fazlası yok; DR. Sadece bir nesne yaratırsınız, ona bir özellik eklersiniz, sonra aynı nesneyi döndürürsünüz. Ardından fabrikayı denetleyicinize ilettiğinizde, nesne üzerindeki bu özellikler artık o denetleyicide fabrikanız aracılığıyla kullanılabilir olacaktır. Daha kapsamlı bir örnek aşağıdadır.
app.factory(‘myFactory’, function(){
var service = {};
return service;
});
Artık 'myFactory' ürününü denetleyicimize ilettiğimizde, 'servise' eklediğimiz özellikleri kullanabiliriz.
Şimdi geri arama fonksiyonumuza bazı 'özel' değişkenler ekleyelim. Bunlara kontrolörden doğrudan erişilemez, ancak sonunda bu 'özel' değişkenleri gerektiğinde değiştirebilmek için 'hizmet' üzerine bazı alıcı / ayarlayıcı yöntemleri kuracağız.
app.factory(‘myFactory’, function($http, $q){
var service = {};
var baseUrl = ‘https://itunes.apple.com/search?term=’;
var _artist = ‘’;
var _finalUrl = ‘’;
var makeUrl = function(){
_artist = _artist.split(‘ ‘).join(‘+’);
_finalUrl = baseUrl + _artist + ‘&callback=JSON_CALLBACK’;
return _finalUrl
}
return service;
});
Burada bu değişkenleri / işlevi 'servise' eklemediğimizi göreceksiniz. Daha sonra kullanmak veya değiştirmek için bunları oluşturuyoruz.
Artık yardımcı / özel değişkenlerimiz ve işlevimiz yerinde olduğuna göre, 'service' nesnesine bazı özellikler ekleyelim. Ne 'hizmet' koymak ne olursa olsun doğrudan 'myFactory' geçmek hangi denetleyici içine kullanılabilir.
Sadece sanatçıyı döndüren veya ayarlayan setArtist ve getArtist yöntemlerini oluşturacağız. Ayrıca, oluşturulan URL'mizle iTunes API'sini çağıracak bir yöntem oluşturacağız. Bu yöntem, veriler iTunes API'sından geri geldiğinde yerine getirecek bir söz verecektir. AngularJS'de vaatler kullanma konusunda fazla deneyiminiz yoksa, onlara derin bir dalış yapmanızı şiddetle tavsiye ederim.
Aşağıda setArtist bir sanatçı kabul eder ve izin verir sen sanatçı ayarlamak için. getArtist sanatçıyı iade eder. callItunes , $ http isteğimizle kullanacağımız URL'yi oluşturmak için önce makeUrl () öğesini çağırır. Daha sonra bir söz nesnesi kurar, nihai URL'mizle $ http isteği yapar, daha sonra $ http bir söz verdiğinden, isteğimizden sonra .success veya .error öğesini çağırabiliriz. Daha sonra iTunes verileriyle olan sözümüzü çözüyoruz veya 'Bir hata oluştu' mesajını reddediyoruz.
app.factory('myFactory', function($http, $q){
var service = {};
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
return _finalUrl;
}
service.setArtist = function(artist){
_artist = artist;
}
service.getArtist = function(){
return _artist;
}
service.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;
}
return service;
});
Şimdi fabrikamız tamamlandı. Artık herhangi bir denetleyiciye 'myFactory' enjekte edebiliyoruz ve daha sonra hizmet neslimize (setArtist, getArtist ve callItunes) eklediğimiz yöntemlerimizi çağırabiliyoruz.
app.controller('myFactoryCtrl', function($scope, myFactory){
$scope.data = {};
$scope.updateArtist = function(){
myFactory.setArtist($scope.data.artist);
};
$scope.submitArtist = function(){
myFactory.callItunes()
.then(function(data){
$scope.data.artistData = data;
}, function(data){
alert(data);
})
}
});
Yukarıdaki kontrolörde 'myFactory' servisine enjekte ediyoruz. Daha sonra 'myFactory' öğesinden gelen verilerle $ scope nesnemizdeki özellikleri ayarlıyoruz. Yukarıdaki tek zor kod, daha önce hiç söz vermediyseniz. CallItunes bir söz veriyorsa, .then () yöntemini kullanabiliriz ve sözümüzü iTunes verileriyle yerine getirdikten sonra yalnızca $ scope.data.artistData ayarlayabiliriz. Denetleyicimizin çok 'ince' olduğunu fark edeceksiniz (Bu iyi bir kodlama uygulamasıdır). Tüm mantık ve kalıcı verilerimiz denetleyicimizde değil, hizmetimizde bulunmaktadır.
2) Hizmet
Bir Hizmet oluştururken bilinmesi gereken en büyük şey, "yeni" anahtar kelimeyle somutlaştırılmasıdır. Sizin için JavaScript guruları, bu size kodun doğası hakkında büyük bir ipucu vermelidir. JavaScript'te sınırlı bir arka plana sahip olanlar veya 'yeni' anahtar kelimenin gerçekte ne yaptığına aşina olmayanlar için, sonunda bir Hizmetin doğasını anlamamıza yardımcı olacak bazı JavaScript temellerini inceleyelim.
'Yeni' anahtar kelimeyle bir işlevi çağırdığınızda meydana gelen değişiklikleri gerçekten görmek için, bir işlev oluşturalım ve onu 'yeni' anahtar kelimeyle çağıralım, ardından yorumlayıcının 'yeni' anahtar kelimeyi gördüğünde ne yaptığını gösterelim. Sonuçların her ikisi de aynı olacaktır.
Önce Yapımcımızı yaratalım.
var Person = function(name, age){
this.name = name;
this.age = age;
}
Bu tipik bir JavaScript yapıcı işlevidir. Şimdi "yeni" anahtar kelimesini kullanarak Kişi işlevini her çağırdığımızda, "bu" yeni oluşturulan nesneye bağlanır.
Şimdi Kişimizin prototipine bir yöntem ekleyelim, böylece Kişinin 'sınıfının' her örneğinde kullanılabilir.
Person.prototype.sayName = function(){
alert(‘My name is ‘ + this.name);
}
Şimdi, sayName işlevini prototipe koyduğumuz için, Person'in her örneği, söz konusu adın adını uyarmak için sayName işlevini çağırabilecektir.
Şimdi kendi prototip üzerinde Kişi yapıcı fonksiyonumuza ve sayName fonksiyonumuza sahip olduğumuza göre, aslında bir Person örneği oluşturalım ve sonra sayName fonksiyonunu çağıralım.
var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’
Yani hep birlikte, bir Kişi yapıcısı oluşturma, prototipine bir işlev ekleme, bir Person örneği oluşturma ve daha sonra işlevi kendi prototipinde çağırmanın kodu şuna benzer.
var Person = function(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
alert(‘My name is ‘ + this.name);
}
var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’
Şimdi JavaScript'te 'yeni' anahtar kelimeyi kullandığınızda gerçekte neler olduğuna bakalım. Dikkat etmemiz gereken ilk şey, örneğimizde 'new' kullandıktan sonra, tıpkı bir nesne gibi sanki 'tyler' üzerinde bir yöntemi (sayName) çağırabileceğimizdir - çünkü. İlk olarak, Kişi kurucumuzun bunu kodda görsün veya görmesek de bir nesneyi döndürdüğünü biliyoruz. İkincisi, sayName işlevimizin doğrudan Person örneğinde değil, prototip üzerinde yer alması nedeniyle, Person işlevinin döndürdüğü nesnenin başarısız aramalardaki prototipine temsilci olması gerektiğini biliyoruz. Daha basit bir ifadeyle, tyler.sayName () öğesini çağırdığımızda yorumlayıcı “Tamam, az önce oluşturduğumuz 'tyler' nesnesine bakacağım, sayName işlevini bulup onu çağıracağım. Bir dakika, burada görmüyorum - tek gördüğüm isim ve yaş, prototipi kontrol edeyim. Yup, prototipte gibi görünüyor, bırak diyeyim. ”.
Aşağıda, 'yeni' anahtar kelimenin JavaScript'te gerçekte ne yaptığını nasıl düşünebileceğinize ilişkin kod bulunmaktadır. Temel olarak yukarıdaki paragrafın bir kod örneğidir. 'Tercüman görünümünü' veya tercümanın notları içindeki kodu görme şeklini koydum.
var Person = 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;
}
Şimdi 'new' anahtar kelimesinin JavaScript'te gerçekte ne yaptığına dair bu bilgiye sahip olmak, AngularJS'de bir Hizmet oluşturmak daha kolay anlaşılmalıdır.
Hizmet oluştururken anlamanız gereken en büyük şey, Hizmetlerin 'yeni' anahtar kelimesiyle somutlaştırıldığını bilmektir. Bu bilgiyi yukarıdaki örneklerimizle birleştirdiğinizde, şimdi özelliklerinizi ve yöntemlerinizi doğrudan 'bu' hizmete ekleyeceğinizi fark etmelisiniz ki bu daha sonra Hizmet'in kendisinden döndürülecektir. Buna eylemde bir göz atalım.
Başlangıçta Fabrika örneğiyle yaptığımızın aksine, bir nesne oluşturmamıza ve o nesneyi döndürmemize gerek yoktur, çünkü daha önce birçok kez belirtildiği gibi, 'yeni' anahtar kelimesini kullandık, böylece yorumlayıcı bu nesneyi oluşturacak, temsilci olsun bu prototip, o zaman biz işi yapmadan bizim için iade et.
İlk önce 'özel' ve yardımcı fonksiyonumuzu oluşturalım. Fabrikamızla aynı şeyi yaptığımız için bu çok tanıdık görünmelidir. Burada her satırın ne yaptığını açıklamayacağım çünkü fabrika örneğinde bunu yaptım, kafanız karıştıysa fabrika örneğini tekrar okuyun.
app.service('myService', function($http, $q){
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
return _finalUrl;
}
});
Şimdi, kontrol cihazımızda mevcut olacak tüm yöntemlerimizi 'buna' ekleyeceğiz.
app.service('myService', function($http, $q){
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
return _finalUrl;
}
this.setArtist = function(artist){
_artist = artist;
}
this.getArtist = function(){
return _artist;
}
this.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;
}
});
Şimdi tıpkı fabrikamızda olduğu gibi, setArtist, getArtist ve callItunes, myService'i hangi denetleyiciye iletirsek kontrol edebiliriz. İşte myService denetleyicisi (neredeyse fabrika denetleyicimizle aynıdır).
app.controller('myServiceCtrl', function($scope, myService){
$scope.data = {};
$scope.updateArtist = function(){
myService.setArtist($scope.data.artist);
};
$scope.submitArtist = function(){
myService.callItunes()
.then(function(data){
$scope.data.artistData = data;
}, function(data){
alert(data);
})
}
});
Daha önce de belirttiğim gibi, 'yeni'nin ne yaptığını gerçekten anladıktan sonra, Hizmetler AngularJS'deki fabrikalarla neredeyse aynıdır.
3) Sağlayıcı
Sağlayıcılar hakkında hatırlanması gereken en büyük şey, uygulamanızın app.config bölümüne geçirebileceğiniz tek hizmet olmasıdır. Hizmet nesnenizin bir kısmını, uygulamanızın başka her yerinde kullanılabilir duruma getirmeden değiştirmeniz gerekiyorsa, bu çok önemlidir. Hizmetlere / Fabrikalara çok benzemesine rağmen, tartışacağımız birkaç farklılık var.
Öncelikle, Hizmet ve Fabrikamızda yaptığımız şekilde Sağlayıcımızı kurduk. Aşağıdaki değişkenler bizim 'özel' ve yardımcı fonksiyonumuzdur.
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;
}
}
* Yine yukarıdaki kodun herhangi bir kısmı kafa karıştırıcıysa, hepsinin daha fazla ayrıntı yaptığını açıkladığım Fabrika bölümüne bakın.
Sağlayıcıları üç bölüme sahip olarak düşünebilirsiniz. İlk bölüm, daha sonra değiştirilecek / ayarlanacak (yukarıda gösterilen) 'özel' değişkenler / işlevlerdir. İkinci bölüm, app.config işlevinizde kullanılabilecek olan değişkenler / işlevlerdir ve bu nedenle başka bir yerde kullanılabilir olmadan önce değiştirilebilecekler (yukarıda da gösterilmiştir). Bu değişkenlerin 'this' anahtar kelimesine iliştirilmesi gerektiğine dikkat etmek önemlidir. Örneğimizde, app.config dosyasında yalnızca 'thingFromConfig' seçeneği kullanılabilir. Üçüncü bölüm (aşağıda gösterilmiştir) 'myProvider' hizmetini belirli bir denetleyiciye aktardığınızda denetleyicinizde kullanılabilecek tüm değişkenler / işlevlerdir.
Sağlayıcı ile bir hizmet oluştururken, denetleyicinizde kullanılabilecek tek özellik / yöntem, $ get () işlevinden döndürülen özellikler / yöntemlerdir. Aşağıdaki kod $ get 'this' değerini koyar (bu fonksiyonun sonunda geri döndürüleceğini biliyoruz). Şimdi, $ get işlevi denetleyicide kullanılabilir olmasını istediğimiz tüm yöntemleri / özellikleri döndürür. İşte bir kod örneği.
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
}
}
Şimdi tam Sağlayıcı kodu şuna benziyor
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;
}
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
}
}
});
Şimdi tıpkı fabrikamızda ve Servisimizde olduğu gibi, setArtist, getArtist ve callItunes, myProvider'ı hangi denetleyiciden geçirdiğimizde kullanılabilir. İşte myProvider denetleyicisi (fabrika / Hizmet denetleyicimizle neredeyse aynı).
app.controller('myProviderCtrl', function($scope, myProvider){
$scope.data = {};
$scope.updateArtist = function(){
myProvider.setArtist($scope.data.artist);
};
$scope.submitArtist = function(){
myProvider.callItunes()
.then(function(data){
$scope.data.artistData = data;
}, function(data){
alert(data);
})
}
$scope.data.thingFromConfig = myProvider.thingOnConfig;
});
Daha önce de belirtildiği gibi, Sağlayıcı ile bir hizmet oluşturmanın tüm amacı, son nesne uygulamanın geri kalanına geçirilmeden önce app.config işlevi aracılığıyla bazı değişkenleri değiştirebilmektir. Bunun bir örneğini görelim.
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';
});
Şimdi 'thingFromConfig' öğesinin sağlayıcımızda nasıl boş bir dize olduğunu görebilirsiniz, ancak bu DOM'da göründüğünde 'Bu cümle ayarlandı…' olacaktır.
Tüm Hizmetler tekil ; uygulama başına bir kez örneklenirler. Bunlar olabilir herhangi bir tür ilkel bir nesne gerçek, fonksiyon ya da özel bir türü, hatta bir örneği olsun.
value
, factory
, service
, constant
, Ve provider
yöntemleri tüm sağlayıcılar vardır. Enjektöre Hizmetleri nasıl somutlaştıracaklarını öğretirler.
En ayrıntılı, aynı zamanda en kapsamlı olanı bir Sağlayıcı tarifi. Kalan dört tarifi türleri - Değer, Fabrika, Hizmet ve Sabit - Bir sağlayıcı tarifi üstünde bir sözdizim güzelliğidir .
Sağlayıcı tarifini yalnızca, uygulama başlamadan önce yapılması gereken uygulama genelinde yapılandırma için bir API'yi ortaya çıkarmak istediğinizde kullanmalısınız. Bu, genellikle davranışları uygulamalar arasında biraz değişmesi gerekebilecek yeniden kullanılabilir hizmetler için ilginçtir.
decorator
.AngularJS Fabrikasını, Hizmetini ve Sağlayıcısını Anlama
Bunların hepsi yeniden kullanılabilir tekli nesneleri paylaşmak için kullanılır. Yeniden kullanılabilir kodu uygulamanızda / çeşitli bileşenlerde / modüllerde paylaşmanıza yardımcı olur.
Dokümanlar Hizmetinden / Fabrikadan :
- Tembel olarak başlatılmış - Açısal yalnızca bir hizmet bileşeni / fabrika, bir uygulama bileşeni buna bağlı olduğunda başlatır.
- Tek Tonlar - Bir hizmete bağımlı her bileşen, hizmet fabrikası tarafından oluşturulan tek örneğe başvuru alır.
Fabrika, bir nesne oluşturmadan önce mantığı değiştirebileceğiniz / ekleyebileceğiniz bir işlevdir, daha sonra yeni oluşturulan nesne döndürülür.
app.factory('MyFactory', function() {
var serviceObj = {};
//creating an object with methods/functions or variables
serviceObj.myFunction = function() {
//TO DO:
};
//return that object
return serviceObj;
});
kullanım
Sadece bir sınıf gibi bir işlevler topluluğu olabilir. Bu nedenle, kontrolörünüze / fabrika / yönerge işlevlerinize enjekte ettiğinizde farklı kontrolörlerde başlatılabilir. Uygulama başına yalnızca bir kez başlatılır.
Sadece hizmetlere bakarken dizi prototipi hakkında düşünün. Hizmet, 'yeni' anahtar kelimeyi kullanarak yeni bir nesneyi başlatan bir işlevdir. this
Anahtar kelimeyi kullanarak bir hizmet nesnesine özellikler ve işlevler ekleyebilirsiniz . Bir fabrikadan farklı olarak, hiçbir şey döndürmez (yöntemler / özellikler içeren bir nesne döndürür).
app.service('MyService', function() {
//directly binding events to this context
this.myServiceFunction = function() {
//TO DO:
};
});
kullanım
Uygulama boyunca tek bir nesneyi paylaşmanız gerektiğinde kullanın. Örneğin, kimliği doğrulanmış kullanıcı ayrıntıları, paylaşılabilir yöntemler / veriler, Yardımcı İşlevler vb.
Bir sağlayıcı yapılandırılabilir bir hizmet nesnesi oluşturmak için kullanılır. Servis ayarını yapılandırma işlevinden yapılandırabilirsiniz. $get()
İşlevi kullanarak bir değer döndürür . $get
İşlev açısal olarak çalıştırma faz üzerinde çalıştırılmaktadır.
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.
};
};
});
kullanım
Hizmet nesnenizi kullanılabilir hale getirmeden önce modül açısından yapılandırma sağlamanız gerektiğinde, ör. Eğer sevdiği Çevre temelinde API URL'sini ayarlamak istediğiniz varsayalım dev
, stage
yaprod
NOT
Hizmet ve fabrika mevcut değilken, açısal yapılandırma aşamasında yalnızca sağlayıcı kullanılabilir.
Umarım bu, Fabrika, Hizmet ve Sağlayıcı hakkındaki anlayışınızı ortadan kaldırmıştır .
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
, bu yüzden kulağa mümkün değil, değil mi?
Benim için vahiy, hepsinin aynı şekilde çalıştığını fark ettiğimde geldi: bir şeyleri bir kez çalıştırarak , aldıkları değeri saklayarak ve sonra bağımlılık enjeksiyonu ile referans verildiğinde aynı depolanmış değeri öksürdüler .
Diyelim ki:
app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);
Üçü arasındaki fark şudur:
a
'nin kayıtlı değeri koşmaktan gelir fn
.b
depolanan değeri new
ing fn
.c
'depolandığını değeri, ilk olarak, bir örneği alma gelen new
ing fn
ve çalışan bir $get
örneğinin yöntemi.Bu, AngularJS içinde her enjeksiyonun değeri yalnızca bir kez, ilk kez enjekte edildiğinde ve bir kez atandığında önbellek nesnesi gibi bir şey olduğu anlamına gelir:
cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()
Bu yüzden this
hizmetlerde kullanıyoruz ve this.$get
sağlayıcılarda a tanımlıyoruz .
factory
s ile iyi gidiyorsun . Var olmasının tek nedeni service
CoffeeScript, TypeScript, ES6 vb. Dillerdir, böylece sınıf sözdizimlerini kullanabilirsiniz. İhtiyacınız provider
Modülünüzün kullanarak farklı ayarlara sahip çeşitli uygulamalarda kullanılan yalnızca s app.config()
. Hizmetiniz saf bir singletonsa veya bir şeyin örneklerini oluşturabiliyorsa, yalnızca uygulamanıza bağlıdır.
Servis vs sağlayıcı vs fabrika:
Basit tutmaya çalışıyorum. Her şey temel JavaScript konseptiyle ilgilidir.
Her şeyden önce, AngularJS'deki hizmetler hakkında konuşalım !
Hizmet Nedir: AngularJS'de Hizmetbazı yararlı yöntemleri veya özellikleri depolayabilen tek bir JavaScript nesnesinden başka bir şey değildir. Bu singleton nesnesi ngApp (Angular app) esasına göre oluşturulur ve mevcut uygulama içindeki tüm kontrolörler arasında paylaşılır. Angularjs bir hizmet nesnesini başlatırken, bu hizmet nesnesini benzersiz bir hizmet adıyla kaydeder. Hizmet örneğine her ihtiyaç duyduğumuzda, Açısal kayıt defterinde bu hizmet adı için arama yapar ve başvuruyu hizmet nesnesine döndürür. Servis nesnesi üzerinde yöntem, erişim özellikleri vb. Denetleyicilerin kapsam nesnesine özellikler, yöntemler de ekleyip ekleyemeyeceğinizle ilgili sorularınız olabilir! Peki neden servis nesnesine ihtiyacınız var? Cevaplar: hizmetler çoklu denetleyici kapsamı arasında paylaşılır. Bazı özellikleri / yöntemleri bir denetleyicinin kapsam nesnesine koyarsanız, yalnızca geçerli kapsamda kullanılabilir.
Üç denetleyici kapsamı varsa, denetleyiciA, denetleyiciB ve denetleyiciC olsun, hepsi aynı hizmet örneğini paylaşacaktır.
<div ng-controller='controllerA'>
<!-- controllerA scope -->
</div>
<div ng-controller='controllerB'>
<!-- controllerB scope -->
</div>
<div ng-controller='controllerC'>
<!-- controllerC scope -->
</div>
Hizmet nasıl oluşturulur?
AngularJS bir servisi kaydetmek için farklı yöntemler sunar. Burada fabrika (..), servis (..), sağlayıcı (..);
Kod başvurusu için bu bağlantıyı kullanın
Bir fabrika fonksiyonunu aşağıdaki gibi tanımlayabiliriz.
factory('serviceName',function fnFactory(){ return serviceInstance;})
AngularJS , serviceName ve JavaScript işlevi olmak üzere iki parametre alan 'factory (' serviceName ', fnFactory)' yöntemini sağlar. Açısal, aşağıdaki gibi fnFactory () işlevini çağırarak hizmet örneği oluşturur .
var serviceInstace = fnFactory();
Aktarılan işlev bir nesneyi tanımlayabilir ve o nesneyi döndürebilir. AngularJS basitçe bu nesne başvurusunu ilk argüman olarak iletilen bir değişkene depolar. FnFactory'den döndürülen her şey serviceInstance öğesine bağlı olacaktır. Nesne döndürmek yerine, işlev, değerler vb.
Misal:
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 object
return data;
});
service('serviceName',function fnServiceConstructor(){})
Başka bir yol, bir hizmet kaydedebiliriz. Tek fark AngularJS'nin hizmet nesnesini somutlaştırmaya çalışmasıdır. Bu kez açısal 'new' anahtar sözcüğünü kullanır ve yapıcı işlevine aşağıdaki gibi bir şey çağırır.
var serviceInstance = new fnServiceConstructor();
Yapıcı işlevinde, hizmet nesnesine özellikler / yöntemler eklemek için 'this' anahtar sözcüğünü kullanabiliriz. misal:
//Creating a service using the service method
var 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);
};
});
Sağlayıcı () işlevi, hizmet oluşturmanın başka bir yoludur. Kullanıcıya karşılama mesajı görüntüleyen bir hizmet oluşturmakla ilgilenelim. Ancak, kullanıcının kendi karşılama iletisini ayarlayabileceği bir işlev de sunmak istiyoruz. Teknik açıdan yapılandırılabilir hizmetler oluşturmak istiyoruz. Bunu nasıl yapabiliriz? Uygulamanın özel karşılama mesajlarını geçebilmesi için bir yol olmalı ve Angularjs bunu hizmetler örneğimizi oluşturan fabrika / kurucu işlevi için kullanılabilir hale getirecektir. Böyle bir durumda sağlayıcı () işlevi işi yapar. sağlayıcı () işlevini kullanarak yapılandırılabilir hizmetler oluşturabiliriz.
Aşağıda verilen sağlayıcı sözdizimini kullanarak yapılandırılabilir hizmetler oluşturabiliriz.
/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});
/*step2:configure the service */
app.config(function configureService(serviceProvider){});
1.Provider nesnesi, sağlayıcı işlevimizde tanımladığımız yapıcı işlevi kullanılarak oluşturulur.
var serviceProvider = new serviceProviderConstructor();
2. app.config () 'de geçirdiğimiz işlev yürütülür. Buna config aşaması denir ve burada hizmetimizi özelleştirme şansımız vardır.
configureService(serviceProvider);
3. son olarak hizmet örneği $ get serviceProvider yöntemi çağrılarak oluşturulur.
serviceInstance = serviceProvider.$get()
var app= angular.module('myApp', []);
app.provider('providerPattern',function providerConstructor(){
//this function works as constructor function for provider
this.firstName = 'Arnold ';
this.lastName = ' Schwarzenegger' ;
this.greetMessage = ' Welcome, This is default Greeting Message' ;
//adding some method which we can call in app.config() function
this.setGreetMsg = function(msg){
if(msg){
this.greetMessage = msg ;
}
};
//We can also add a method which can change firstName and lastName
this.$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 ?');
}
);
Özet:
Fabrika ayarı, bir servis örneği döndüren bir fabrika işlevi kullanır. serviceInstance = fnFactory ();
Hizmet bir yapıcı işlevi kullanır ve Angular, hizmet örneğini oluşturmak için 'new' anahtar sözcüğünü kullanarak bu yapıcı işlevini çağırır. serviceInstance = new fnServiceConstructor ();
Sağlayıcı bir providConstructor işlevi tanımlar, bu sağlayıcıConstructor işlevi $ get fabrika işlevini tanımlar . Açısal hizmet nesnesi oluşturmak için $ get () işlevini çağırır. Sağlayıcı sözdiziminin, hizmet nesnesini somutlaştırılmadan önce yapılandırma avantajı vardır. serviceInstance = $ get ();
Burada birkaç kişinin işaret ettiği gibi, bir fabrika, sağlayıcı, hizmet ve hatta değer ve sabit aynı şeyin versiyonlarıdır. Daha genel provider
olanların hepsini parçalara ayırabilirsiniz . Şöyle ki:
İşte bu resim şu makaleden geliyor:
AngularJS'ye bir işlev verirsiniz, fabrika istendiğinde AngularJS önbelleğe alır ve dönüş değerini enjekte eder.
Misal:
app.factory('factory', function() {
var name = '';
// Return value **is** the object that will be injected
return {
name: name;
}
})
Kullanımı:
app.controller('ctrl', function($scope, factory) {
$scope.name = factory.name;
});
Sen angularjs bir işlev vermek, angularjs arayacak yeni bir örneğini oluşturmaya. AngularJS'nin hizmet istendiğinde önbelleğe alınacak ve enjekte edilecek örneğidir. Yana yeni hizmet örneğini kullanıldı, keyword bu geçerlidir ve örneğine karşılık gelir.
Misal:
app.service('service', function() {
var name = '';
this.setName = function(newName) {
name = newName;
}
this.getName = function() {
return name;
}
});
Kullanımı:
app.controller('ctrl', function($scope, service) {
$scope.name = service.getName();
});
AngularJS'ye bir işlev verirsiniz ve AngularJS $get
işlevini çağırır . $get
Hizmet istendiğinde önbelleğe alınacak ve enjekte edilecek olan işlevin dönüş değeridir .
Sağlayıcılar, AngularJS enjekte edilemeyen yöntemi çağırmadan önce sağlayıcıyı yapılandırmanıza izin verir $get
.
Misal:
app.provider('provider', function() {
var name = '';
this.setName = function(newName) {
name = newName;
}
this.$get = function() {
return {
name: name
}
}
})
Kullanım (kontrolörde enjekte edilebilir olarak)
app.controller('ctrl', function($scope, provider) {
$scope.name = provider.name;
});
Kullanım ( $get
enjektabl oluşturmak için sağlayıcıyı önceden yapılandırmak için çağrılır)
app.config(function(providerProvider) {
providerProvider.setName('John');
});
Sağlayıcılarla oynarken ilginç bir şey fark ettim.
Enjektablların görünürlüğü, sağlayıcılar için servisler ve fabrikalardan farklıdır. Bir AngularJS "sabiti" (örneğin myApp.constant('a', 'Robert');
) bildirirseniz , bunu hizmetlere, fabrikalara ve sağlayıcılara enjekte edebilirsiniz.
Ancak bir AngularJS "değeri" (örneğin. myApp.value('b', {name: 'Jones'});
) Bildirirseniz, bunu hizmetlere ve fabrikalara enjekte edebilirsiniz, ancak sağlayıcı oluşturma işlevine DEĞİL. Bununla birlikte, bunu $get
sağlayıcınız için tanımladığınız işleve enjekte edebilirsiniz . Bu AngularJS belgelerinde belirtilmiştir, ancak kaçırılması kolaydır. Değer ve sabit yöntemlerle ilgili bölümlerde bunu% sağlama sayfasında bulabilirsiniz.
<div ng-app="MyAppName">
<div ng-controller="MyCtrl">
<p>from Service: {{servGreet}}</p>
<p>from Provider: {{provGreet}}</p>
</div>
</div>
<script>
var myApp = angular.module('MyAppName', []);
myApp.constant('a', 'Robert');
myApp.value('b', {name: 'Jones'});
myApp.service('greetService', function(a,b) {
this.greeter = 'Hi there, ' + a + ' ' + b.name;
});
myApp.provider('greetProvider', function(a) {
this.firstName = a;
this.$get = function(b) {
this.lastName = b.name;
this.fullName = this.firstName + ' ' + this.lastName;
return this;
};
});
function MyCtrl($scope, greetService, greetProvider) {
$scope.servGreet = greetService.greeter;
$scope.provGreet = greetProvider.fullName;
}
</script>
Bu acemi için çok kafa karıştırıcı bir parçası ve kolay kelimelerle açıklığa kavuşturmaya çalıştım
AngularJS Hizmeti: yardımcı program işlevlerini denetleyicideki hizmet başvurusuyla paylaşmak için kullanılır. Hizmet tekil niteliktedir, bu nedenle bir hizmet için tarayıcıda yalnızca bir örnek oluşturulur ve sayfa boyunca aynı başvuru kullanılır.
Hizmette, işlev adlarını bu nesne ile özellik olarak oluştururuz .
AngularJS Fabrikası: Fabrikanın amacı Hizmet ile aynıdır, ancak bu durumda yeni bir nesne oluşturur ve bu nesnenin özellikleri olarak işlevler ekleriz ve sonunda bu nesneyi döndürürüz.
AngularJS Sağlayıcısı: bunun amacı yine aynıdır, ancak Sağlayıcı $ get işlevinin çıktısını verir.
Hizmet, Fabrika ve Sağlayıcının tanımlanması ve kullanılması http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider adresinde açıklanmaktadır.
Benim için farkı anlamanın en iyi ve en basit yolu:
var service, factory;
service = factory = function(injection) {}
AngularJS belirli bileşenleri nasıl başlatır (basitleştirilmiş):
// service
var angularService = new service(injection);
// factory
var angularFactory = factory(injection);
Bu nedenle, hizmet için AngularJS bileşeni, sınıfın hizmet bildirme işlevi tarafından temsil edilen nesne örneğidir. Fabrika için, fabrika bildirim işlevinden döndürülen sonuçtur. Fabrika, servisle aynı şekilde davranabilir:
var factoryAsService = function(injection) {
return new function(injection) {
// Service content
}
}
En basit düşünme şekli şudur:
Fabrika 'sınıf' örneği, etrafındaki yorumlarda ve sağlayıcı farkında verilmiştir.
new MyService()
falan mümkün olacağını bekliyordum :)
Bu konuda açıklamam:
Temel olarak, bahsedilen tüm türler (servis, fabrika, sağlayıcı, vb.) Sadece eski moda küresel değişkenler gibi küresel değişkenler (tabii ki tüm uygulama için küresel olan) oluşturuyor ve yapılandırıyorlar.
Global değişkenler önerilmese de, bu global değişkenlerin gerçek kullanımı , değişkeni ilgili denetleyiciye geçirerek bağımlılık enjeksiyonu sağlamaktır .
"Global değişkenler" için değer yaratmanın birçok seviyesi vardır:
app.config
app.config
dönüş değeri "global" değişkenleri başlatmak için kullanılır. Aşağıda benim anlayışım çok basit.
Fabrika: Fabrika içinde bir nesne oluşturup iade edersiniz.
Hizmet:
Bir işlevi tanımlamak için bu anahtar sözcüğü kullanan standart bir işleve sahipsiniz.
Sağlayıcı:
$get
Tanımladığınız bir nesne var ve veri döndüren nesneyi almak için kullanılabilir.
Açısal dokümanlardan özet :
SO'dan en iyi yanıtlar:
https://stackoverflow.com/a/26924234/165673 (<- İYİ)
https://stackoverflow.com/a/27263882/165673
https://stackoverflow.com/a/16566144/165673
Tüm iyi cevaplar zaten. Hizmet ve Fabrika'ya birkaç nokta daha eklemek istiyorum . Hizmet / fabrika arasındaki fark ile birlikte. Ve ayrıca şöyle sorular da olabilir:
Hizmet ve fabrika arasındaki farkla başlayalım:
Her ikisi de Singletons : Açısal bunları ilk kez bağımlılık olarak bulduğunda, tek bir hizmet / fabrika örneği oluşturur. Örnek oluşturulduktan sonra, aynı örnek sonsuza kadar kullanılır.
Davranışla bir nesneyi modellemek için kullanılabilir : Her ikisinin de yöntemleri, iç durum değişkenleri vb. Olabilir . Bu kodu yazma şekliniz farklı olsa da.
Hizmetler:
Hizmet yapıcı bir işlevdir ve Angular yeni çağrı ile hizmeti başlatır yourServiceName()
. Bu birkaç şey demektir.
this
.new yourServiceName(
), this
nesneyi üzerine koyduğunuz tüm özelliklere sahip olur.Örnek Örnek:
angular.service('MyService', function() {
this.aServiceVariable = "Ved Prakash"
this.aServiceMethod = function() {
return //code
};
});
Angular bu
MyService
hizmeti ona bağlı bir denetleyiciye enjekte ettiğinde, o denetleyiciMyService
işlevlerini çağırabileceği bir denetime sahip olur , örneğin MyService.aServiceMethod ().
Dikkatli olunthis
:
Oluşturulan hizmet bir nesne olduğundan, içindeki yöntemler çağrıldığında buna başvurabilir:
angular.service('ScoreKeeper', function($http) {
this.score = 0;
this.getScore = function() {
return this.score;
};
this.setScore = function(newScore) {
this.score = newScore;
};
this.addOne = function() {
this.score++;
};
});
Sen aramak için cazip olabilir ScoreKeeper.setScore
sunucudan onu kapma tarafından skoru başlatıldı eğer örneğin bir söz zincirinde: $http.get('/score').then(ScoreKeeper.setScore).
Bu noktadaki sorunsa yani ScoreKeeper.setScore
anılmaktadır this
bağlı null
ve hatalarla elde edersiniz. Daha iyi bir yol olurdu $http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper))
. Bunu hizmet yöntemlerinizde kullanmayı tercih edip etmediğinizi, nasıl aradığınıza dikkat edin.
A değerinden bir değer döndürmeService
:
JavaScript kurucularının çalışma şekli nedeniyle (i.e., an Object)
, bir constructor
işlevden karmaşık bir değer döndürürseniz , arayan bu örnek yerine bu Nesneyi alır.
Temelde, aşağıdan fabrika örneğini kopyalayıp yapıştırmak yerine geçebileceğini Bu araçlar factory
ile service
ve bu ödeme şekli:
angular.service('MyService', function($http) {
var api = {};
api.aServiceMethod= function() {
return $http.get('/users');
};
return api;
});
Böylece Angular hizmetinizi yeni MyService () ile oluşturduğunda, MyService örneği yerine o api nesnesini alır.
Bu, herhangi bir karmaşık değerin (nesneler, işlevler) davranışıdır, ancak ilkel türler için değildir.
Fabrikalar:
Fabrika, bir değer döndüren eski bir işlevdir. Dönüş değeri, fabrikaya bağlı olan şeylere enjekte edilen değerdir. Açısal'daki tipik bir fabrika deseni, şu özelliklere sahip işlevlere sahip bir nesneyi döndürmektir:
angular.factory('MyFactory', function($http) {
var api = {};
api.aFactoryMethod= function() {
return $http.get('/users');
};
return api;
});
Fabrika bağımlılığı için enjekte edilen değer fabrikanın dönüş değeridir ve bir nesne olması gerekmez. Bir işlev olabilir
Yukarıdaki 1 ve 2 sorularının cevapları:
Çoğunlukla, her şey için fabrikaları kullanmaya devam edin. Davranışlarını anlamak daha kolaydır. Bir değer döndürüp döndürmeyeceğine dair bir seçenek yoktur ve ayrıca yanlış bir şey yaparsanız tanıtılacak hiçbir hata yoktur.
Yine de bağımlılık olarak enjekte etmekten bahsettiğimde hala onlara “hizmet” diyorum.
Hizmet / Fabrika davranışı çok benzer ve bazı insanlar her ikisinin de iyi olduğunu söyleyecektir. Bu biraz doğru, ama John Papa'nın stil rehberinin tavsiyelerini takip etmeyi ve sadece fabrikalara bağlı kalmayı daha kolay buluyorum. **
Ek bir açıklama, fabrikaların hizmetler / ilkeller oluşturabilmesine karşın, hizmetler yapamaz. Epokk'in temel aldığı bu jsFiddle'a göz atın: http://jsfiddle.net/skeller88/PxdSP/1351/ .
Fabrika, çağrılabilecek bir işlev döndürür:
myApp.factory('helloWorldFromFactory', function() {
return function() {
return "Hello, World!";
};
});
Fabrika ayrıca çağrılabilecek bir yöntemle bir nesneyi döndürebilir:
myApp.factory('helloWorldFromFactory', function() {
return {
sayHello: function() {
return "Hello, World!";
}
};
});
Hizmet, çağrılabilecek bir yönteme sahip bir nesne döndürür:
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!";
};
});
Daha fazla ayrıntı için, fark hakkında yazdığım bir gönderiye bakın: http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/
Zaten iyi cevaplar var, ama sadece bunu paylaşmak istiyorum.
Her şeyden önce: Sağlayıcı , service
$ enjektör tarafından enjekte edilmesi gereken bir (singleton nesnesi) yaratmanın yolu / reçetesidir (AngulaJS, IoC paterninden nasıl geçer).
Ve Değer, Fabrika, Hizmet ve Sabit (4 yol) - Sağlayıcı yolu / alıcı üzerinde sözdizimsel şeker .
Ele alınan Service vs Factory
kısım var:
https://www.youtube.com/watch?v=BLzNCkPn3ao
Hizmetnew
aslında bildiğimiz gibi 4 şey yapar anahtar kelime hakkında :
prototype
nesnesine bağlarcontext
içinthis
this
Ve Fabrika tamamen Fabrika Kalıbı ile ilgilidir - bu Hizmet gibi Nesneleri döndüren işlevler içerir.
Ve bu basit / kısa video: ayrıca Sağlayıcıyı da kapsar : https://www.youtube.com/watch?v=HvTZbQ_hUZY (orada fabrikadan sağlayıcıya nasıl geçtiklerini görebilirsiniz)
Sağlayıcı tarifi, uygulama tamamen başlatılmadan / başlatılmadan önce çoğunlukla uygulama yapılandırmasında kullanılır.
Tüm bu yazıyı okuduktan sonra benim için daha fazla kafa karıştırdı .. Ama yine de hepsi değerli bilgiler .. sonunda basit karşılaştırma ile bilgi verecek aşağıdaki tabloyu buldum
Ve yeni başlayanlar için: - Bu kullanım durumunu düzeltemeyebilir, ancak yüksek düzeyde bu üçü için kullanım alanı budur.
angular.module('myApp').config(function($testProvider){
$testProvider.someFunction();
})
Temel senaryolar için fabrika ve Servis aynı şekilde davranır.
İşte AngularjS'de nesne fabrikası için bir kod şablonu olarak bulduğum bazı broilerplate kodu. Örnek olarak bir Car / CarFactory kullandım. Denetleyicide basit uygulama kodunu yapar.
<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 in
if (value === undefined) {
// and a default value was specified
if (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)
return this;
}; // end this.set()
}; // end this.Car class definition
// instance properties default values
this.Car.prototype.defaults = {
color: 'yellow',
numberOfDoors: 2,
hasLeatherSeats: null,
hasFancyRadio: false
};
// instance factory method / constructor
this.Car.prototype.instance = function(params) {
return new
this.constructor()
.set('color', params.color)
.set('numberOfDoors', params.numberOfDoors)
.set('hasFancyRadio', params.hasFancyRadio)
.set('hasLeatherSeats', params.hasLeatherSeats)
;
};
return new this.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>
İşte daha basit bir örnek. Enlem ve boylam, ancak farklı nesne özellikleri açığa "Pozisyon" bir nesne bekliyoruz birkaç üçüncü taraf kitaplıkları kullanıyorum. Satıcı kodunu kesmek istemedim, bu yüzden etrafta dolaştığım "Konum" nesnelerini ayarladım.
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;
return this;
};
this.setLongitude = function(longitude) {
this.longitude = longitude;
this.lon = longitude;
this.coords.longitude = longitude;
return this;
};
}; // end class definition
// instance factory method / constructor
this.Position.prototype.instance = function(params) {
return new
this.constructor()
.setLatitude(params.latitude)
.setLongitude(params.longitude)
;
};
return new this.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
;
Bu sayfaya ve belgelere referans olarak kullanma (son baktığımdan beri büyük ölçüde iyileşmiş gibi görünüyor) , sağlayıcının 5 lezzetinden 4'ünü kullanan aşağıdaki gerçek (-ish) dünya demosunu bir araya getirdim; Değer, Sabit, Fabrika ve tam gelişmiş Sağlayıcı.
HTML:
<div ng-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>
<button ng-click="main.handleClick()">Click me to earn</button>
<small>* Not actual money</small>
</div>
Uygulamanın
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 CONSTANT
return Math.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.
var Money = 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 currency
this.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 value
Money.prototype.addThousandSeparator = function(value, symbol) {
return value.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', function MoneyProvider() {
var locale;
// Function called by the config to set up the provider
this.setLocale = function(value) {
locale = value;
};
// All providers need to implement a $get method which returns
// an instance of the custom class which constitutes the service
this.$get = function moneyFactory() {
return new Money(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 @ runtime
this.earned = money.convertValue(0);
this.handleClick = function() {
this.count ++;
this.earned = money.convertValue(random * this.count);
};
});
Çalışma demosu .
Bu cevap konuyu / soruyu ele alıyor
VEYA
temelde ne olur
Bir yaptığınızda factory()
size ayarlar function
sağlayıcısının ikinci argüman sağlanan $get
ve onu (dönüş provider(name, {$get:factoryFn })
) ama elde ettiğin provider
ancak başka hiçbir özellik / yöntem yoktur$get
Bunun provider
(bu yapılandıramazsınız yollarla)
Fabrika kaynak kodu
function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
};
Bunu yaparken, service()
(fabrikada hizmetinizde verdiğiniz yapıcı örneğini döndüren) function
enjekte eden bir fabrika ( constructor
) sağlar ve iade eder
Kaynak hizmet kodu
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
};
Temel olarak her iki durumda da sonunda bir sağlayıcıya sağladığınız işlevinize $ set alırsınız, ancak yapılandırma bloğu için orijinal olarak sağlayıcıda () sağlayabileceğiniz gibi $ get dışında bir şey verebilirsiniz.
Ben çok mükemmel bir cevap biliyorum ama varsayılan
1 service
çoğu durumda 1. kullanma deneyimimi paylaşmak zorunda
2. factory
belirli bir örnek hizmet oluşturmak için kullanılır
// factory.js ////////////////////////////
(function() {
'use strict';
angular
.module('myApp.services')
.factory('xFactory', xFactoryImp);
xFactoryImp.$inject = ['$http'];
function xFactoryImp($http) {
var fac = function (params) {
this._params = params; // used for query params
};
fac.prototype.nextPage = function () {
var url = "/_prc";
$http.get(url, {params: this._params}).success(function(data){ ...
}
return fac;
}
})();
// service.js //////////////////////////
(function() {
'use strict';
angular
.module('myApp.services')
.service('xService', xServiceImp);
xServiceImp.$inject = ['$http'];
function xServiceImp($http) {
this._params = {'model': 'account','mode': 'list'};
this.nextPage = function () {
var url = "/_prc";
$http.get(url, {params: this._params}).success(function(data){ ...
}
}
})();
ve kullanma:
controller: ['xFactory', 'xService', function(xFactory, xService){
// books = new instance of xFactory for query 'book' model
var books = new xFactory({'model': 'book', 'mode': 'list'});
// accounts = new instance of xFactory for query 'accounts' model
var accounts = new xFactory({'model': 'account', 'mode': 'list'});
// accounts2 = accounts variable
var accounts2 = xService;
...
Partiye biraz geç. Ama bunun fabrika, hizmet ve sağlayıcı metodolojilerini kullanarak Angular JS Custom Services geliştirmeyi öğrenmek (veya netleştirmek) isteyenler için daha yararlı olduğunu düşündüm.
AngularJS Özel Hizmetlerini geliştirmek için fabrika, hizmet ve sağlayıcı yöntemleri hakkında net bir açıklama yapan bu videoyla karşılaştım:
https://www.youtube.com/watch?v=oUXku28ex-M
Kaynak Kodu: http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service
Burada yayınlanan kod, okuyucuların yararlanması için doğrudan yukarıdaki kaynaktan kopyalanır.
"Fabrika" tabanlı özel hizmet kodu aşağıdaki gibidir (hem senkronizasyon hem de zaman uyumsuz sürümlerle birlikte http hizmetini çağırır):
var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcFactory',
function($scope, calcFactory) {
$scope.a = 10;
$scope.b = 20;
$scope.doSum = function() {
//$scope.sum = calcFactory.getSum($scope.a, $scope.b); //synchronous
calcFactory.getSum($scope.a, $scope.b, function(r) { //aynchronous
$scope.sum = r;
});
};
}
]);
app.factory('calcFactory', ['$http', '$log',
function($http, $log) {
$log.log("instantiating calcFactory..");
var oCalcService = {};
//oCalcService.getSum = function(a,b){
// return parseInt(a) + parseInt(b);
//};
//oCalcService.getSum = function(a, b, cb){
// var s = parseInt(a) + parseInt(b);
// cb(s);
//};
oCalcService.getSum = function(a, b, cb) { //using http service
$http({
url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
method: 'GET'
}).then(function(resp) {
$log.log(resp.data);
cb(resp.data);
}, function(resp) {
$log.error("ERROR occurred");
});
};
return oCalcService;
}
]);
Özel Hizmetler için "hizmet" metodolojisi kodu (bu, 'fabrika'ya oldukça benzer, ancak sözdizimi açısından farklıdır):
var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
$scope.a = 10;
$scope.b = 20;
$scope.doSum = function(){
//$scope.sum = calcService.getSum($scope.a, $scope.b);
calcService.getSum($scope.a, $scope.b, function(r){
$scope.sum = r;
});
};
}]);
app.service('calcService', ['$http', '$log', function($http, $log){
$log.log("instantiating calcService..");
//this.getSum = function(a,b){
// return parseInt(a) + parseInt(b);
//};
//this.getSum = function(a, b, cb){
// var s = parseInt(a) + parseInt(b);
// cb(s);
//};
this.getSum = function(a, b, cb){
$http({
url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
method: 'GET'
}).then(function(resp){
$log.log(resp.data);
cb(resp.data);
},function(resp){
$log.error("ERROR occurred");
});
};
}]);
Özel Hizmetler için "sağlayıcı" metodolojisi kodu (bu, yapılandırılabilecek bir hizmet geliştirmek istiyorsanız gereklidir):
var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
$scope.a = 10;
$scope.b = 20;
$scope.doSum = function(){
//$scope.sum = calcService.getSum($scope.a, $scope.b);
calcService.getSum($scope.a, $scope.b, function(r){
$scope.sum = r;
});
};
}]);
app.provider('calcService', function(){
var baseUrl = '';
this.config = function(url){
baseUrl = url;
};
this.$get = ['$log', '$http', function($log, $http){
$log.log("instantiating calcService...")
var oCalcService = {};
//oCalcService.getSum = function(a,b){
// return parseInt(a) + parseInt(b);
//};
//oCalcService.getSum = function(a, b, cb){
// var s = parseInt(a) + parseInt(b);
// cb(s);
//};
oCalcService.getSum = function(a, b, cb){
$http({
url: baseUrl + '/Sum?a=' + a + '&b=' + b,
method: 'GET'
}).then(function(resp){
$log.log(resp.data);
cb(resp.data);
},function(resp){
$log.error("ERROR occurred");
});
};
return oCalcService;
}];
});
app.config(['calcServiceProvider', function(calcServiceProvider){
calcServiceProvider.config("http://localhost:4467");
}]);
Son olarak, yukarıdaki hizmetlerden herhangi biriyle çalışan kullanıcı arayüzü:
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js" ></script>
<script type="text/javascript" src="t03.js"></script>
</head>
<body ng-app="app">
<div ng-controller="emp">
<div>
Value of a is {{a}},
but you can change
<input type=text ng-model="a" /> <br>
Value of b is {{b}},
but you can change
<input type=text ng-model="b" /> <br>
</div>
Sum = {{sum}}<br>
<button ng-click="doSum()">Calculate</button>
</div>
</body>
</html>
AngularJS kaynağından bir şeyi açıklığa kavuşturmak için, bir hizmetin fabrika işlevini çağırdığını ve bunun karşılığında sağlayıcı işlevini çağırdığını görebilirsiniz:
function factory(name, factoryFn) {
return provider(name, { $get: factoryFn });
}
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
AngularJS'de iş mantığını ele almanın üç yolunu basit bir şekilde tartışalım: ( Yaakov'un Coursera AngularJS kursundan esinlenildi )
HİZMET :
Sözdizimi:
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 files
function ServiceExampleController(NameOfTheService){
serviceExampleController = this;
serviceExampleController.data = NameOfTheService.getSomeData();
}
function NameOfTheService(){
nameOfTheService = this;
nameOfTheService.data = "Some Data";
nameOfTheService.getSomeData = function(){
return nameOfTheService.data;
}
}
index.html
<div ng-controller = "ServiceExampleController as serviceExample">
{{serviceExample.data}}
</div>
Hizmet Özellikleri:
FABRİKA
Önce sözdizimine bir göz atalım:
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 function
function NameOfTheFactoryOne(){
var factory = function(){
return new SomeService();
}
return factory;
}
//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
var factory = {
getSomeService : function(){
return new SomeService();
}
};
return factory;
}
Şimdi denetleyicide yukarıdaki ikisini kullanarak:
var factoryOne = NameOfTheFactoryOne() //since it returns a function
factoryOne.someMethod();
var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
factoryTwo.someMethod();
Fabrika Özellikleri:
.service()
Yöntem olduğu fabrika her zaman tekil olan hizmetin aynı tür, üretir ve 's davranışını yapılandırmak için herhangi bir kolay yolu olmadan. Bu .service()
yöntem genellikle herhangi bir yapılandırma gerektirmeyen bir şey için kısayol olarak kullanılır.SAĞLAYICI
İlk önce sözdizimine bir göz atalım:
angular.module('ProviderModule', [])
.controller('ProviderModuleController', ProviderModuleController)
.provider('ServiceProvider', ServiceProvider)
.config(Config); //optional
Config.$inject = ['ServiceProvider'];
function Config(ServiceProvider) {
ServiceProvider.defaults.maxItems = 10; //some default value
}
ProviderModuleController.$inject = ['ServiceProvider'];
function ProviderModuleController(ServiceProvider) {
//some methods
}
function ServiceProvider() {
var provider = this;
provider.defaults = {
maxItems: 10
};
provider.$get = function () {
var someList = new someListService(provider.defaults.maxItems);
return someList;
};
}
}
Sağlayıcının Özellikleri:
.service
veya .factory
yöntemle yapılandırdığımızda, sağlayıcı yönteminin perde arkasında yürütülen şey olduğu belirtilmektedir .$get
, doğrudan sağlayıcı örneğine eklenmiş bir işlevdir. Bu işlev fabrika işlevidir. Başka bir deyişle, bu yöntemi sağlamak için kullandığımız gibi .factory
. Bu fonksiyonda kendi servisimizi yaratıyoruz. Bu $get
özellik, bu bir işlev, sağlayıcıyı sağlayıcı yapan şeydir . AngularJS, sağlayıcının değeri Angular'ın fabrika işlevi olarak değerlendireceği bir işlev olan bir $ get özelliğine sahip olmasını bekler. Ancak bu tüm sağlayıcı kurulumunu çok özel kılan şey config
, servis sağlayıcısının içinde bir nesne sağlayabilmemiz ve genellikle adımda, tüm uygulamayı yapılandırabileceğimiz varsayılanların üzerine gelebilmemizdir.Fabrika: Fabrika içinde bir nesne oluşturduğunuz ve iade ettiğiniz fabrika.
service: Hizmet, işlevi tanımlamak için bu anahtar sözcüğü kullanan standart bir işleve sahiptir.
sağlayıcı: Sağlayıcı sizin tanımladığınız bir $ var ve veriyi döndüren nesneyi almak için kullanılabilir.
Temel olarak, Sağlayıcı, Fabrika ve Hizmetin tümü Servis'tir. Tek ihtiyacınız olan bir $ get () işlevi olduğunda, daha az kodla yazmanıza olanak tanıyan bir Fabrika, Hizmetin özel bir halidir.
Hizmetler, Fabrikalar ve Sağlayıcılar arasındaki en büyük fark karmaşıklıklarıdır. Hizmetler en basit biçimdir, Fabrikalar biraz daha sağlamdır ve Sağlayıcılar çalışma zamanında yapılandırılabilir.
Her birinin ne zaman kullanılacağına dair bir özet:
Fabrika : Verdiğiniz değerin diğer verilere göre hesaplanması gerekir.
Hizmet : Bir nesneyi yöntemlerle döndürüyorsunuz.
Sağlayıcı : Yapılandırma aşamasında oluşturulacak nesneyi oluşturulmadan önce yapılandırabilirsiniz. Uygulama tamamen başlatılmadan önce Sağlayıcıyı çoğunlukla uygulama yapılandırmasında kullanın.
1.Servisler, gerektiğinde oluşturulan ve uygulama yaşam döngüsünün sonuna kadar (tarayıcı kapatıldığında) asla temizlenmeyen tekli nesnelerdir. Kontrolörler artık ihtiyaç duyulmadığında yok edilir ve temizlenir.
2.Hizmet oluşturmanın en kolay yolu factory () yöntemini kullanmaktır. Factory () yöntemi, hizmet işlevlerini ve hizmet verilerini içeren bir nesneyi döndürerek bir hizmeti tanımlamamıza olanak tanır. Hizmet tanımı işlevi, $ http ve $ q gibi enjekte edilebilir hizmetlerimizi yerleştirdiğimiz yerdir. Ör:
angular.module('myApp.services')
.factory('User', function($http) { // injectables go here
var backendUrl = "http://localhost:3000"; var service = {
// our factory definition
user: {},
setName: function(newName) {
service.user['name'] = newName;
},
setEmail: function(newEmail) { service.user['email'] = newEmail;
},
save: function() {
return $http.post(backendUrl + '/users', { user: service.user
}); }
};
return service; });
Bizim app fabrika () kullanma
Uygulamamızda fabrikayı kullanmak kolaydır, çünkü çalışma zamanında ihtiyacımız olan yere enjekte edebiliriz.
angular.module('myApp')
.controller('MainController', function($scope, User) {
$scope.saveUser = User.save;
});
Sözdizimsel Şeker farktır . Yalnızca sağlayıcı gereklidir. Ya da başka bir deyişle, sadece sağlayıcı gerçek açısaldır, diğer tüm kodlar türetilir (kodu azaltmak için). Ayrıca, yalnızca değer döndüren, hesaplama veya işlev döndürmeyen Value () adlı basit bir sürüm de vardır. Hatta Değer sağlayıcıdan türetilir!
Peki neden bu tür komplikasyonlar, neden sadece sağlayıcıyı kullanamıyoruz ve diğer her şeyi unutamıyoruz? Kolayca kod yazmamıza ve daha iyi iletişim kurmamıza yardımcı olması gerekiyor. Ve yanaktan yana cevap, bir çerçevenin satışını ne kadar karmaşık hale getirirse o kadar karmaşık olur.
Açısal enjeksiyon bize bu sonuca varmada ilk ipucunu veriyor.
"$ injector, fabrika tarafından değil, hizmet sağlayıcı tarafından değil, hizmet sağlayıcı tarafından tanımlanan nesne örneklerini almak için kullanılır .
Ve daha iyi bir cevap şöyle olur: "Açısal bir hizmet, bir servis fabrikası tarafından oluşturulur. Bu hizmet fabrikaları, bir servis sağlayıcı tarafından oluşturulan işlevlerdir. Servis sağlayıcıları yapıcı işlevleridir. $ get adlı, hizmet fabrikası işlevini tutar. "
Yani ana sağlayıcı ve enjektör ve hepsi yerinde düşecek :). IServiceProvider'dan devralınarak $ get'in bir sağlayıcıda uygulanabilmesi, Typescript'te ilginç hale geliyor.