Bunun yerine, tabloyu "evet" ve "hayır" ile hiçbir açıklama yapmadan doldurmak yerine, biraz daha ayrıntıya gireceğim.
[Not, bitirdikten sonra eklendi: Bu sona erdi ... beklediğimden biraz daha uzun. Altta bir tl var; ama umarım bu bilgilendirici olur.]
[Bu cevap AngularJS wiki'ye eklenmiştir: Bağımlılık Enjeksiyonunu Anlamak ]
$provide
Hizmet nasıl yeni enjektabl şeyler oluşturmak için açısal anlatan sorumludur; bunlara hizmet denir . Hizmetler, sağlayıcılar olarak adlandırılan şeylerle tanımlanır ; bu, kullandığınızda oluşturduğunuz şeydir $provide
. Bir sağlayıcı tanımlamak provider
, $provide
hizmet üzerindeki yöntemle yapılır ve $provide
bir uygulamanın config
işlevine enjekte edilmesini isteyerek hizmeti alabilirsiniz . Bir örnek şöyle olabilir:
app.config(function($provide) {
$provide.provider('greeting', function() {
this.$get = function() {
return function(name) {
alert("Hello, " + name);
};
};
});
});
Burada greeting
; adlı bir hizmet için yeni bir sağlayıcı tanımladık ; greeting
herhangi bir enjekte edilebilir işleve ( değişkenler gibi daha sonraları) adlandırılan bir değişkeni enjekte edebiliriz ve Angular $get
, hizmetin yeni bir örneğini döndürmek için sağlayıcının işlevini çağıracaktır . Bu durumda, enjekte edilecek şey , isme dayalı bir name
parametre ve alert
sa mesajı alan bir işlevdir . Bunu şu şekilde kullanabiliriz:
app.controller('MainController', function($scope, greeting) {
$scope.onClick = function() {
greeting('Ford Prefect');
};
});
Şimdi işte püf noktası. factory
,, service
ve value
hepsi bir sağlayıcının çeşitli bölümlerini tanımlamak için kısayollardır - yani, tüm bu şeyleri yazmak zorunda kalmadan bir sağlayıcı tanımlamak için bir araç sağlarlar. Örneğin, aynı sağlayıcıyı şu şekilde yazabilirsiniz :
app.config(function($provide) {
$provide.factory('greeting', function() {
return function(name) {
alert("Hello, " + name);
};
});
});
Ben başka bir şekilde ifade edeceğiz, bu yüzden anlamak önemlidir: başlık altında, angularjs çağırıyor kodun aynısını biz (yukarıda yazdığı $provide.provider
sürümü) için bize. Kelimenin tam anlamıyla, iki versiyonda% 100 fark yoktur. value
aynı şekilde çalışır - $get
fonksiyonumuzdan ne dönersek (aka factory
fonksiyonumuz) her zaman aynı ise, kullanarak daha az kod yazabiliriz value
. Örneğin, greeting
hizmetimiz için her zaman aynı işlevi döndürdüğümüz için , bunu value
tanımlamak için de kullanabiliriz :
app.config(function($provide) {
$provide.value('greeting', function(name) {
alert("Hello, " + name);
});
});
Yine, bu, bu işlevi tanımlamak için kullandığımız diğer iki yöntemle% 100 özdeştir - bu, biraz yazmayı kaydetmenin bir yoludur.
Muhtemelen kullandığım bu sinir bozucu app.config(function($provide) { ... })
şeyi fark ettiniz . Yeni sağlayıcılar tanımlamak ( yukarıda verilen yöntemlerden herhangi biri aracılığıyla ) çok yaygın olduğundan, AngularJS $provider
yöntemleri daha da fazla yazmak için yöntemleri doğrudan modül nesnesine maruz bırakır :
var myMod = angular.module('myModule', []);
myMod.provider("greeting", ...);
myMod.factory("greeting", ...);
myMod.value("greeting", ...);
Bunların hepsi, daha app.config(...)
önce kullandığımız daha ayrıntılı sürümlerle aynı şeyi yapıyor .
Şimdiye kadar atladığım enjektabl constant
. Şimdilik, aynı şekilde çalıştığını söylemek yeterince kolay value
. Sonradan bir fark göreceğiz.
İnceleme için , tüm bu kod parçaları yapıyoruz tam aynı şeyi:
myMod.provider('greeting', function() {
this.$get = function() {
return function(name) {
alert("Hello, " + name);
};
};
});
myMod.factory('greeting', function() {
return function(name) {
alert("Hello, " + name);
};
});
myMod.value('greeting', function(name) {
alert("Hello, " + name);
});
Enjektör, sağladığımız kodu kullanarak hizmetlerimizin örneklerini oluşturmaktan sorumludur $provide
(cezalandırma amaçlı değildir). Enjekte edilen argümanları alan bir işlev yazdığınızda, enjektörü iş başında görürsünüz. Her AngularJS uygulamasında, $injector
uygulama ilk başlatıldığında oluşturulan bir tane vardır; $injector
Enjekte edilebilir herhangi bir işleve enjekte ederek onu tutabilirsiniz (evet, $injector
kendini nasıl enjekte edeceğini bilir!)
Elinize geçtikten sonra , hizmetin adıyla $injector
arayarak tanımlı bir hizmetin örneğini alabilirsiniz get
. Örneğin,
var greeting = $injector.get('greeting');
greeting('Ford Prefect');
Enjektör ayrıca hizmetlerin işlevlere enjekte edilmesinden de sorumludur; örneğin, enjektör invoke
yöntemini kullanarak hizmetleri herhangi bir işleve sihirli bir şekilde enjekte edebilirsiniz ;
var myFunction = function(greeting) {
greeting('Ford Prefect');
};
$injector.invoke(myFunction);
Enjektörün sadece bir kez bir servis örneği oluşturacağını belirtmek gerekir . Daha sonra, sağlayıcının hizmet adıyla döndürdüğü her şeyi önbelleğe alır; bir dahaki sefere hizmeti istediğinizde, tam olarak aynı nesneyi alırsınız.
Böylece, sorunuzu cevaplamak için , çağrılan herhangi bir işleve$injector.invoke
hizmetler enjekte edebilirsiniz . Bu içerir
- denetleyici tanımı fonksiyonları
- yönerge tanımlama fonksiyonları
- filtre tanımlama fonksiyonları
$get
(aka sağlayıcılarının yöntemleri factory
tanımı fonksiyonları)
Yana constant
ler ve value
her zaman statik bir değer döndürmek s, onlar enjektör vasıtasıyla çağrılan, olup, dolayısı onlarla iğne şeyle yapamazsınız.
Sağlayıcıları Yapılandırma
Herkes ile tam teşekküllü sağlayıcı kurmak neden rahatsız ediyor olabilirsiniz provide
yöntemle eğer factory
, value
çok daha kolaydır, vb. Cevap, sağlayıcıların çok fazla yapılandırmaya izin vermesidir. Sağlayıcı aracılığıyla bir hizmet oluşturduğunuzda (veya Angular'ın size sağladığı kısayollardan herhangi birinde), bu hizmetin nasıl oluşturulduğunu tanımlayan yeni bir sağlayıcı oluşturduğunuzdan daha önce bahsetmiştik. Ne vermedi söz bu sağlayıcılar enjekte edilebilir olmasıdır config
onlarla etkileşim kurabilmek için uygulamanızın bölümlerinde!
İlk olarak, Açısal uygulamanızı iki aşamada ( config
ve run
aşamaları) çalıştırır. config
Gerekli gibi herhangi sağlayıcıları ayarlayabilirsiniz nereye faz, gördüğümüz gibi olduğunu. Burası aynı zamanda direktiflerin, kontrolörlerin, filtrelerin ve benzerlerinin ayarlandığı yerdir. run
Tahmin edeceğiniz gibi Eğik aslında DOM derler ve uygulamanızı başladığı aşama vardır.
Ek kod ile bu aşamada çalıştırılacak ekleyebilir myMod.config
ve myMod.run
fonksiyonları - Her bu özel aşamasında çalıştırmak için bir işlev alır. İlk bölümde gördüğümüz gibi, bu fonksiyonlar enjekte edilebilir - $provide
ilk kod örneğimize dahili servisi enjekte ettik. Bununla birlikte, dikkat edilmesi gereken şey, aşama sırasında config
sadece sağlayıcıların enjekte edilebilmesidir ( AUTO
modüldeki hizmetler hariç - $provide
ve $injector
).
Örneğin, aşağıdakilere izin verilmez :
myMod.config(function(greeting) {
// WON'T WORK -- greeting is an *instance* of a service.
// Only providers for services can be injected in config blocks.
});
Ne yapmak herhangi vardır erişimi sağlayıcılar Yaptığınız hizmetler için:
myMod.config(function(greetingProvider) {
// a-ok!
});
Önemli bir istisna vardır: constant
değiştirilemedikleri için config
blokların içine enjekte edilmelerine izin verilir ( value
s'den farklı olmaları budur ). Bunlara yalnızca isimleriyle erişilir ( Provider
sonek gerekmez).
Eğer bir hizmet için bir sağlayıcı tanımlanmış zaman, o sağlayıcı olarak adlandırılmış serviceProvider
nerede, service
hizmetin adıdır. Şimdi sağlayıcıların gücünü daha karmaşık şeyler yapmak için kullanabiliriz!
myMod.provider('greeting', function() {
var text = 'Hello, ';
this.setText = function(value) {
text = value;
};
this.$get = function() {
return function(name) {
alert(text + name);
};
};
});
myMod.config(function(greetingProvider) {
greetingProvider.setText("Howdy there, ");
});
myMod.run(function(greeting) {
greeting('Ford Prefect');
});
Şimdi hizmet sağlayıcımızda setText
, özelleştirmek için kullanabileceğimiz bir fonksiyonumuz var alert
; config
bu yöntemi çağırmak ve hizmeti özelleştirmek için bu sağlayıcıya bir blokta erişebiliriz . Sonunda bizim app çalıştırmak, biz greeting
hizmet kapmak ve bizim özelleştirme etkili olduğunu görmek için deneyebilirsiniz.
Bu daha karmaşık bir örnek olduğundan, işleyen bir gösteri: http://jsfiddle.net/BinaryMuse/9GjYg/
Denetleyici işlevleri enjekte edilebilir, ancak denetleyicilerin kendileri başka şeylere enjekte edilemez. Bunun nedeni denetleyicilerin sağlayıcı aracılığıyla oluşturulmamasıdır. Bunun yerine, $controller
denetleyicilerinizi kurmaktan sorumlu yerleşik bir Açısal hizmet vardır . Aradığınızda myMod.controller(...)
, aslında erişiyorsanız bu hizmetin sağlayıcısı sadece son bölümde olduğu gibi.
Örneğin, böyle bir denetleyici tanımladığınızda:
myMod.controller('MainController', function($scope) {
// ...
});
Aslında yaptığınız şey:
myMod.config(function($controllerProvider) {
$controllerProvider.register('MainController', function($scope) {
// ...
});
});
Daha sonra, Angular'ın denetleyicinizin bir örneğini oluşturması gerektiğinde, $controller
hizmeti kullanır (bu da $injector
denetleyicinizin işlevini çağırmak için kullanır, böylece bağımlılıkları da enjekte edilir).
Filtreler ve Yönergeler
filter
ve directive
tam olarak aynı şekilde çalışır controller
; filter
Bir denir hizmeti kullanan $filter
ve sağlayıcı $filterProvider
iken directive
bir hizmet olarak adlandırılan kullanımları $compile
ve sağlayıcı $compileProvider
. Bazı bağlantılar:
Diğer örneklere göre myMod.filter
ve myMod.directive
bu hizmetleri yapılandırmak için kısayollardır.
Özetlemek gerekirse, çağrılan herhangi bir fonksiyon $injector.invoke
enjekte edilebilir . Bu, grafiğinizden (ancak bunlarla sınırlı değildir) şunları içerir:
- kontrolör
- direktif
- fabrika
- filtre
- sağlayıcı
$get
(sağlayıcıyı nesne olarak tanımlarken)
- sağlayıcı işlevi (sağlayıcıyı yapıcı işlevi olarak tanımlarken)
- hizmet
Sağlayıcı, şeylere enjekte edilebilen yeni hizmetler oluşturur . Bu içerir:
- sabit
- fabrika
- Sağlayıcı
- hizmet
- değer
Yani gibi hizmetler dahili dedi $controller
ve $filter
olabilir enjekte edilecek ve yapabilecekleriniz kullanmak , kendileri tarafından bu yöntemlerden (tanımladığınız şeyler değildir halde tanımlanmış yeni filtreleri ve denetleyicileri ele almak için bu hizmeti, muktedir şeylere enjekte edilir).
Bunun dışında, enjektör tarafından başlatılan herhangi bir işlev sağlayıcı tarafından sağlanan herhangi bir hizmetle enjekte edilebilir - herhangi bir kısıtlama yoktur ( burada listelenen config
ve run
farklılıklar dışında ).