इसके बजाय कि "हां" और "नहीं" के साथ तालिका में बिना किसी स्पष्टीकरण के भरें, मैं थोड़ा और अधिक विस्तार में जाऊंगा।
[नोट, परिष्करण के बाद जोड़ा गया: यह समाप्त हो रहा है ... मुझे उम्मीद से थोड़ा अधिक लंबा। वहाँ एक tl है; डॉ। तल पर; लेकिन मुझे आशा है कि यह सूचनात्मक साबित होता है।]
[इस जवाब को AngularJS wiki: Understanding Dependency Injection ] में भी जोड़ा गया है।
$provide
सेवा कोणीय बता कैसे नए इंजेक्शन चीज़ें बनाने के लिए उत्तरदायी है; इन चीजों को सेवा कहा जाता है । सेवा प्रदाताओं द्वारा बताई गई चीजों को परिभाषित किया जाता है , जिसे आप उपयोग करते समय बनाते हैं $provide
। एक प्रदाता को परिभाषित करना सेवा provider
पर विधि के माध्यम से किया जाता है $provide
, और आप $provide
किसी एप्लिकेशन के config
फ़ंक्शन में इंजेक्ट होने के लिए कहकर सेवा को पकड़ सकते हैं । एक उदाहरण कुछ इस तरह हो सकता है:
app.config(function($provide) {
$provide.provider('greeting', function() {
this.$get = function() {
return function(name) {
alert("Hello, " + name);
};
};
});
});
यहां हमने एक नई प्रदाता को सेवा के लिए परिभाषित किया है greeting
; हम greeting
किसी भी इंजेक्टेबल फंक्शन (जैसे कि बाद में, उस पर अधिक) में नामित वैरिएबल को इंजेक्ट कर सकते हैं और एंगुलर सेवा के $get
एक नए उदाहरण को वापस करने के लिए प्रदाता के फ़ंक्शन को कॉल करेंगे । इस मामले में, जो चीज इंजेक्ट की जाएगी वह एक फ़ंक्शन है जो नाम के आधार पर एक name
पैरामीटर और alert
एक संदेश लेता है । हम इसे इस तरह उपयोग कर सकते हैं:
app.controller('MainController', function($scope, greeting) {
$scope.onClick = function() {
greeting('Ford Prefect');
};
});
अब यहाँ चाल है। factory
, service
और value
सभी एक प्रदाता के विभिन्न भागों को परिभाषित करने के लिए सिर्फ शॉर्टकट हैं - अर्थात्, वे एक प्रदाता को परिभाषित करने का एक साधन प्रदान करते हैं, जिसमें वह सभी सामग्री टाइप करने के बिना। उदाहरण के लिए, आप ठीक उसी प्रदाता को इस तरह लिख सकते हैं :
app.config(function($provide) {
$provide.factory('greeting', function() {
return function(name) {
alert("Hello, " + name);
};
});
});
यह समझना महत्वपूर्ण है, इसलिए मैं पुनः विचार करूंगा: हुड के तहत, AngularJS ठीक उसी कोड को कॉल कर रहा है जो हमने हमारे लिए ऊपर ( $provide.provider
संस्करण) लिखा था । शाब्दिक रूप से, दो संस्करणों में 100% कोई अंतर नहीं है। ठीक उसी तरह से काम करता है - अगर हम जो भी अपने फंक्शन (उर्फ हमारे फंक्शन) से लौटते हैं, वह हमेशा ठीक वैसा ही होता है, तो हम कोड यूज करके भी लिख सकते हैं । उदाहरण के लिए, चूंकि हम हमेशा अपनी सेवा के लिए एक ही फ़ंक्शन वापस करते हैं, इसलिए हम इसे परिभाषित करने के लिए भी उपयोग कर सकते हैं :value
$get
factory
value
greeting
value
app.config(function($provide) {
$provide.value('greeting', function(name) {
alert("Hello, " + name);
});
});
फिर, यह इस फ़ंक्शन को परिभाषित करने के लिए हमारे द्वारा उपयोग की गई अन्य दो विधियों के समान 100% है - यह केवल कुछ टाइपिंग को बचाने का एक तरीका है।
अब आप शायद इस कष्टप्रद app.config(function($provide) { ... })
बात पर गौर कर रहे हैं जिसका मैं उपयोग कर रहा हूं नए प्रदाताओं को परिभाषित करने के बाद ( ऊपर दिए गए किसी भी तरीके के माध्यम से) इतना सामान्य है, एंगुलरजेएस $provider
और भी टाइपिंग को बचाने के लिए सीधे मॉड्यूल ऑब्जेक्ट पर विधियों को उजागर करता है :
var myMod = angular.module('myModule', []);
myMod.provider("greeting", ...);
myMod.factory("greeting", ...);
myMod.value("greeting", ...);
ये सभी वही क्रिया करते हैं जो app.config(...)
पहले इस्तेमाल किए गए अधिक वर्बोज़ संस्करणों के रूप में होती हैं ।
अभी तक मैंने जो एक इंजेक्शन छोड़ा है वह है constant
। अभी के लिए, यह कहना काफी आसान है कि यह ठीक वैसे ही काम करता है value
। हम देखेंगे कि बाद में एक अंतर है।
समीक्षा करने के लिए , ये सभी कोड सटीक समान कार्य कर रहे हैं :
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);
});
इंजेक्टर वास्तव में हमारे द्वारा प्रदान किए गए कोड का उपयोग करके हमारी सेवाओं के उदाहरण बनाने के लिए ज़िम्मेदार है $provide
(कोई सज़ा नहीं)। किसी भी समय आप एक फ़ंक्शन लिखते हैं जो इंजेक्शन को तर्क देता है, आप काम पर इंजेक्टर देख रहे हैं। प्रत्येक AngularJS एप्लिकेशन में एक सिंगल है $injector
जो तब बनता है जब एप्लिकेशन पहली बार शुरू होता है; आप $injector
किसी भी इंजेक्टेबल फंक्शन में इंजेक्ट करके इसकी पकड़ प्राप्त कर सकते हैं (हाँ, $injector
खुद को इंजेक्ट करना जानते हैं!)
आपके पास एक बार $injector
, आप सेवा get
के नाम से कॉल करके परिभाषित सेवा का एक उदाहरण प्राप्त कर सकते हैं । उदाहरण के लिए,
var greeting = $injector.get('greeting');
greeting('Ford Prefect');
इंजेक्टर कार्यों में सेवाओं को इंजेक्ट करने के लिए भी जिम्मेदार है; उदाहरण के लिए, आप जादुई तरीके से इंजेक्टर की invoke
विधि का उपयोग करके किसी भी फ़ंक्शन में सेवाओं को इंजेक्ट कर सकते हैं ;
var myFunction = function(greeting) {
greeting('Ford Prefect');
};
$injector.invoke(myFunction);
यह ध्यान देने योग्य है कि इंजेक्टर केवल एक बार सेवा का एक उदाहरण बना देगा । यह तब कैश करता है जो प्रदाता सेवा के नाम से लौटता है; अगली बार जब आप सेवा के लिए कहेंगे, तो आप वास्तव में उसी वस्तु को प्राप्त करेंगे।
तो, अपने प्रश्न का उत्तर देने के लिए, आप किसी भी फ़ंक्शन$injector.invoke
में सेवाओं को इंजेक्ट कर सकते हैं जिसे साथ बुलाया जाता है । यह भी शामिल है
- नियंत्रक परिभाषा कार्य
- निर्देश परिभाषा कार्य
- फ़िल्टर परिभाषा कार्य
$get
प्रदाताओं के तरीके ( factory
परिभाषा कार्य उर्फ )
चूँकि constant
s और value
s हमेशा एक स्थैतिक मान लौटाते हैं, उन्हें इंजेक्टर के माध्यम से नहीं लगाया जाता है, और इस प्रकार आप उन्हें किसी भी चीज़ से इंजेक्ट नहीं कर सकते हैं।
प्रदाताओं को कॉन्फ़िगर करना
आप सोच रहे होंगे कि कोई भी इस provide
पद्धति से पूर्ण-प्रदाता प्रदान करने की जहमत क्यों उठाएगा factory
, अगर value
इत्यादि बहुत आसान हैं। इसका उत्तर यह है कि प्रदाता बहुत सारे कॉन्फ़िगरेशन की अनुमति देते हैं। हमने पहले ही उल्लेख किया है कि जब आप प्रदाता के माध्यम से एक सेवा बनाते हैं (या कोई भी शॉर्टकट जो आपको कोणीय देता है), आप एक नया प्रदाता बनाते हैं जो यह बताता है कि उस सेवा का निर्माण कैसे किया जाता है। मैंने क्या उल्लेख नहीं किया है कि इन प्रदाताओं config
को आपके आवेदन के अनुभागों में इंजेक्ट किया जा सकता है ताकि आप उनके साथ बातचीत कर सकें!
सबसे पहले, कोणीय दो चरणों में आपका आवेदन चलाता है - config
और run
चरण। config
चरण, हमने देखा कि के रूप में, आप आवश्यक के रूप में किसी भी प्रदाताओं सेट कर सकते हैं जहां है। यह वह जगह भी है जहां निर्देशक, नियंत्रक, फिल्टर, और जैसे सेट हो जाते हैं। run
चरण, के रूप में आप अनुमान लगा सकता है, जहां कोणीय वास्तव में अपने डोम संकलित करता है तथा अपने अनुप्रयोग शुरू होता है।
आप इन चरणों में myMod.config
और myMod.run
कार्यों के साथ चलाने के लिए अतिरिक्त कोड जोड़ सकते हैं - प्रत्येक उस विशिष्ट चरण के दौरान चलाने के लिए एक फ़ंक्शन लेते हैं। जैसा कि हमने पहले खंड में देखा था, ये फ़ंक्शन इंजेक्टेबल हैं - हमने $provide
अपने पहले कोड नमूने में अंतर्निहित सेवा को इंजेक्ट किया । हालांकि, ध्यान देने योग्य बात यह है कि चरण के दौरान config
, केवल प्रदाताओं को इंजेक्ट किया जा सकता है ( AUTO
मॉड्यूल में सेवाओं के अपवाद के साथ - $provide
और $injector
)।
उदाहरण के लिए, निम्नलिखित की अनुमति नहीं है :
myMod.config(function(greeting) {
// WON'T WORK -- greeting is an *instance* of a service.
// Only providers for services can be injected in config blocks.
});
आपके पास जो भी सेवाएँ हैं उनके लिए आपके पास कोई भी प्रदाता है:
myMod.config(function(greetingProvider) {
// a-ok!
});
एक महत्वपूर्ण अपवाद है: constant
एस, चूंकि उन्हें बदला नहीं जा सकता है, उन्हें config
ब्लॉकों के अंदर इंजेक्ट करने की अनुमति है (यह इस प्रकार है कि वे value
एस से अलग हैं )। वे अकेले अपने नाम से Provider
पहुंचते हैं (कोई आवश्यक प्रत्यय नहीं)।
जब भी आपने किसी सेवा के लिए प्रदाता को परिभाषित किया है, तो उस प्रदाता का नाम हो जाता है serviceProvider
, जहां service
सेवा का नाम होता है। अब हम प्रदाताओं की शक्ति का उपयोग कर सकते हैं कुछ और अधिक जटिल सामान करते हैं!
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');
});
अब हमारे पास हमारे प्रदाता पर एक फ़ंक्शन है जिसे setText
हम अनुकूलित करने के लिए उपयोग कर सकते हैं alert
; हम config
इस पद्धति को कॉल करने और सेवा को अनुकूलित करने के लिए एक ब्लॉक में इस प्रदाता तक पहुंच प्राप्त कर सकते हैं । जब हम अंत में अपना ऐप चलाते हैं, तो हम इस greeting
सेवा को पकड़ सकते हैं , और यह देखने की कोशिश कर सकते हैं कि हमारा अनुकूलन प्रभावी हुआ।
चूँकि यह एक अधिक जटिल उदाहरण है, यहाँ एक कार्य प्रदर्शन है: http://jsfiddle.net/BinaryMuse/9GYYY/
नियंत्रक कार्यों में इंजेक्ट किया जा सकता है, लेकिन नियंत्रकों को खुद को अन्य चीजों में इंजेक्ट नहीं किया जा सकता है। ऐसा इसलिए है क्योंकि प्रदाता के माध्यम से नियंत्रक नहीं बनाए जाते हैं। इसके बजाय, एक अंतर्निहित कोणीय सेवा है जिसे कहा जाता है $controller
कि आपके नियंत्रक स्थापित करने के लिए जिम्मेदार है। जब आप कॉल करते हैं myMod.controller(...)
, तो आप वास्तव में इस सेवा के प्रदाता तक पहुंच बना रहे हैं , जैसे पिछले अनुभाग में।
उदाहरण के लिए, जब आप एक नियंत्रक को इस तरह परिभाषित करते हैं:
myMod.controller('MainController', function($scope) {
// ...
});
आप वास्तव में यह क्या कर रहे हैं:
myMod.config(function($controllerProvider) {
$controllerProvider.register('MainController', function($scope) {
// ...
});
});
बाद में, जब कोणीय को आपके नियंत्रक का एक उदाहरण बनाने की आवश्यकता होती है, तो यह $controller
सेवा का उपयोग करता है (जो बदले में $injector
आपके नियंत्रक फ़ंक्शन को लागू करने के लिए उपयोग करता है ताकि इसे इसकी निर्भरताएं भी इंजेक्शन मिलें)।
फिल्टर और निर्देश
filter
और directive
ठीक उसी तरह काम करते हैं जैसे controller
; filter
एक सेवा $filter
और उसके प्रदाता का उपयोग करता है $filterProvider
, जबकि directive
एक सेवा $compile
और उसके प्रदाता का उपयोग करता है $compileProvider
। कुछ लिंक:
अन्य उदाहरणों के अनुसार, myMod.filter
और myMod.directive
इन सेवाओं को कॉन्फ़िगर करने के लिए शॉर्टकट हैं।
इसलिए, संक्षेप में, किसी भी फ़ंक्शन को जिसे बुलाया जाता $injector.invoke
है, में इंजेक्ट किया जा सकता है । इसमें आपके चार्ट से (लेकिन यह सीमित नहीं है) शामिल है:
- नियंत्रक
- आदेश
- फ़ैक्टरी
- फिल्टर
- प्रदाता
$get
(जब एक वस्तु के रूप में प्रदाता को परिभाषित करना)
- प्रदाता फ़ंक्शन (जब निर्माता फ़ंक्शन को निर्माता फ़ंक्शन के रूप में परिभाषित करता है)
- सर्विस
प्रदाता नई सेवाएँ बनाता है जिन्हें चीजों में इंजेक्ट किया जा सकता है । यह भी शामिल है:
- स्थिर
- फ़ैक्टरी
- प्रदाता
- सर्विस
- मूल्य
उस ने कहा, अंतर्निहित सेवाओं की तरह है $controller
और इंजेक्ट किया $filter
जा सकता है, और आप उपयोग कर सकते हैं उन फ़िल्टर और नियंत्रकों को उन तरीकों से परिभाषित करने के लिए उन सेवाओं का (भले ही आपके द्वारा परिभाषित की गई चीजें स्वयं द्वारा सक्षम न हों, चीजों में इंजेक्ट किया गया)।
इसके अलावा, किसी भी इंजेक्टर-इनवोक किए गए फ़ंक्शन को किसी भी प्रदाता द्वारा प्रदान की गई सेवा के साथ इंजेक्ट किया जा सकता है - कोई प्रतिबंध नहीं है ( यहां सूचीबद्ध config
और run
मतभेदों के अलावा )।