2012-11-28 17 views
20

के माध्यम से एक नया उदाहरण वापस करने के लिए बताएं उपयोग का मामला सरल है: मेरे पास दो नियंत्रक समान निर्भरता साझा करते हैं MyService। इस सेवा में कुछ राज्य है, myVariable बैठे हैं। अगर मैं इसे ControllerOne से सेट करता हूं, तो इसे ControllerTwo द्वारा भी देखा जाएगा।एंगुलरजेस को निर्भरता इंजेक्शन

मैं चाहता हूं कि प्रत्येक नियंत्रक के पास MyService का अपना उदाहरण हो, ताकि myVariable को प्रत्येक नियंत्रक द्वारा दूसरे को प्रभावित किए बिना बदला जा सके।

दूसरे शब्दों में कहें - मैं नया उदाहरण चाहते बल्कि सिंगलटन से, निर्भरता इंजेक्शन द्वारा दिए जाते।

+0

भी http://stackoverflow.com/a/13620494/215945 –

उत्तर

20

जैसा कि आप सीधे उम्मीद कर सकते हैं। सेवा उदाहरण पहली बार इंजेक्टर द्वारा पुनर्प्राप्त किए जाते हैं और इंजेक्टर द्वारा बनाए जाते हैं ... दूसरे शब्दों में, वे हमेशा सिंगलेट होते हैं। The magic happens in here, विशेष रूप से provider फ़ंक्शन पर देखें, जो प्रदाता उदाहरण को प्रदाता कैश ऑब्जेक्ट में रखता है।

लेकिन आशा खोना नहीं है, तो आप बस के रूप में आसानी से कंस्ट्रक्टर्स जो कुछ के लिए है यह आप एक सेवा में साझा करना चाहते हैं यदि आप ऐसा चुना है जोड़ सकते हैं:

app.factory('myService', [function() { 
    var i = 1; 

    function Foo() { 
     this.bar = "I'm Foo " + i++; 
    }; 

    return { 
      Foo: Foo 
    }; 
}]); 

app.controller('Ctrl1', function($scope, myService) { 
    $scope.foo = new myService.Foo(); 
    console.log($scope.foo.bar) //I'm Foo 1 
}); 

app.controller('Ctrl2', function($scope, myService) { 
    $scope.foo = new myService.Foo(); 
    console.log($scope.foo.bar) //I'm Foo 2 
}); 

संपादित करें: के रूप में ओ पी ने कहा, $injector.instantiate भी है, जिसका उपयोग आप अपने नियंत्रक के बाहर जावास्क्रिप्ट कन्स्ट्रक्टर को कॉल करने के लिए कर सकते हैं। मुझे यकीन नहीं है कि यहां टेस्टेबिलिटी के प्रभाव क्या हैं, लेकिन यह आपको कोड इंजेक्ट करने का एक और तरीका प्रदान करता है जो आपके लिए एक नई वस्तु का निर्माण करेगा।

+4

देखें वहाँ भी एक और तरीका है। आप केवल आवश्यक निर्भरताओं (घटक एक्स) के साथ एक ऑब्जेक्ट बना सकते हैं और फिर इसे '$ injector.instantiate (ComponentX, {})' के साथ सीधे इंजेक्ट कर सकते हैं। दूसरे तर्क में सभी 'स्टेटफुल' चर शामिल हो सकते हैं। आसान और सुरुचिपूर्ण, आपको कोणीय जेएस धन्यवाद! शायद आप इसे वैकल्पिक समाधान के रूप में अपनी प्रतिक्रिया में जोड़ सकते हैं, कृपया? –

+1

परीक्षण करने के लिए कठिन लग रहा है। –

+0

समाधान होने लगता है, लेकिन आपको केवल निर्माता को वापस करने की आवश्यकता है। अन्य सभी विधियों को आप एक तरफ लौट सकते हैं, जो आप बाद में बनाएंगे किसी भी उदाहरण को प्रभावित नहीं करेंगे, सिवाय इसके कि यदि आप उन्हें अपने कन्स्ट्रक्टर के प्रोटोटाइप में जोड़ते हैं ... karlgold उत्तर देखें, जो लगभग सही है। –

3

जावा स्क्रिप्ट कोड modularizing के लिए सामान्य बहुत सारे विकल्प हैं, लेकिन अगर आप कुछ है कि AngularJS पर पूरी तरह निर्भर करता है क्या करना चाहते हैं, इस पद्धति काम करता है:

1) प्रथम श्रेणी है कि आप कई बार इंजेक्षन करना चाहते हैं निर्धारित करें:

angular.module('myModule').constant('MyClass', MyClass); 

3) अंत में, बनाने के लिए कारखाना पैटर्न का उपयोग करें:

function MyClass() { 
    // ... 
} 

MyClass.prototype.memberMethod = function() { 
    // ... 
} 

2) इसके बाद, निर्माता एक निरंतर रूप में उपलब्ध करा नाम है, वर्ग के इंजेक्शन उदाहरणों:

angular.module('myOtherModule', ['myModule']).factory('instanceOfMyClass', [ 
    'MyClass', 
    function(MyClass) { return new MyClass(); } 
]); 
+0

अच्छा विचार। लेकिन यह काम नहीं करता है अगर आपके प्रोटोटाइप को इंजेक्शन की आवश्यकता होती है जो स्थिरांक के साथ नहीं किया जा सकता है, न तो मूल्य ... इस मामले में, मुझे लगता है कि एक सेवा बनाना एक बेहतर विकल्प है। –

संबंधित मुद्दे