एक AngularJS सेवा के लिए वर्तमान गुंजाइश पारित करना


106

क्या "करंट" $scopeको एंगुलरजेएस सेवा में पास करना सही है ?

मैं उस स्थिति में हूं जहां मैंने एक $ सेवा को जाना है, केवल एक नियंत्रक द्वारा इसका सेवन किया जाता है, और मैं खुद $ सेवा विधियों में नियंत्रक के दायरे का संदर्भ लेना चाहूंगा।

क्या यह दार्शनिक रूप से सही है?

या मैं $ rootScope पर घटनाओं को प्रसारित करना बेहतर करूंगा और फिर अपने नियंत्रक को उनकी बात सुनूंगा?


1
क्या आप शायद हमें विशेष रूप से बता सकते हैं कि आप क्या करने का प्रयास कर रहे हैं? शायद सेवा में गुंजाइश को बढ़ाने के लिए आवश्यक नहीं है?
गणराज

खैर, यह इतना मुश्किल नहीं है। बस, मैं चाहता हूँ कि जब जरूरत हो , $scopeगुणों को प्राप्त $scope.$applyकर सकें और कॉल कर सकें।
SC

इसके अलावा, यह कहें कि मैं $ स्कोप पर $ सर्विस से आने वाले बदलावों को लागू करना चाहता हूं। उम्मीद है कि अब यह स्पष्ट है।
SC

8
मेरा सुझाव है कि आप $ गुंजाइश गुण हैं जो आप चाहते हैं कि आपकी सेवा स्वयं सेवा (नियंत्रक में होने के बजाय) में पहुंच सके। कंट्रोलर्स की तुलना में मॉडल / डेटा स्टोर करने के लिए सेवाएं बेहतर स्थान हैं।
मार्क राजकॉक

@MarkRajcock मैं इस मुद्दे को भी समझने की कोशिश कर रहा हूँ। वर्तमान में मैं सिर्फ एक सेवा को कॉल कर रहा हूं और नियंत्रक को दिए गए डेटा को संलग्न कर रहा हूं $scope... नियंत्रक सीधे सेवा में डेटा तक कैसे पहुंचेगा और इसे किए बिना इसे पास कर सकता है?
drjimmie1976

जवाबों:


67

कंट्रोलर को यह बताने के लिए कि जब कुछ असंकल होता है, तो कोणीय वादों का उपयोग करें ।

इसे भड़काने के लिए $apply, आपको स्कोप की आवश्यकता नहीं है, आप कॉल कर सकते हैं $rootScope.$apply, क्योंकि किसी विशिष्ट स्कोप या रूट में कॉल करने में कोई अंतर नहीं है।

वैरिएबल रीडिंग के संबंध में, यदि आप पैरामीटर प्राप्त करते हैं तो बेहतर होगा। लेकिन आप इसे एक पैरामीटर से ऑब्जेक्ट पैरामीटर के रूप में भी पढ़ सकते हैं, लेकिन मैं पैरामीटर के साथ जाऊंगा, जिससे आपकी सेवा इंटरफ़ेस बहुत अधिक स्पष्ट हो जाएगा।


मुझे लगता है कि यह वह उत्तर है जो मेरे एंगुलरजेएस शुरुआती संदेह को बेहतर ढंग से हल करता है।
SC

@Caio Cunha क्या आप इस बात का विस्तार कर सकते हैं कि एक गुंजाइश पारित करना एक अच्छा विचार क्यों नहीं है? मैं वास्तव में इस मुद्दे पर हूँ, मैं $scopeएक async executeSql()फ़ंक्शन का उपयोग करके किसी सेवा में कॉल के माध्यम से कुछ सामान जोड़ना चाहता हूं । 3 विकल्पों (1) में देखकर async फ़ंक्शन पर कॉलबैक का उपयोग करें, फिर कॉल करें $scope.$apply... यह काम करता है, लेकिन बदसूरत (2) $scopeasync फ़ंक्शन में पास होता है, फिर कॉल करें theScope.$apply()... यह भी काम करता है (3) एक वादे का उपयोग करें। ..नहीं अभी तक यह कोशिश की। एक वादा सबसे अच्छा तरीका क्यों है? धन्यवाद!
drjimmie1976

15

मैं कहूंगा कि यदि आपकी कार्यक्षमता केवल एक नियंत्रक के लिए विशिष्ट है, तो आपको सेवा की आवश्यकता नहीं है।

नियंत्रक कार्य विशिष्ट मॉडल में हेरफेर करना है जबकि एक सेवा को वैश्विक कार्यों से निपटना चाहिए। मैं चीजों को मिलाने के बजाय इस प्रतिमान पर टिकूंगा।

डॉक्स का यही कहना है

सर्विस

कोणीय सेवाएं एकल हैं जो वेब एप्लिकेशन के लिए विशिष्ट कार्यों को सामान्य रूप से पूरा करती हैं

नियंत्रक

कोणीय में, एक नियंत्रक एक जावास्क्रिप्ट फ़ंक्शन (प्रकार / वर्ग) है जो मूल दायरे को छोड़कर कोणीय स्कोप के उदाहरणों को बढ़ाने के लिए उपयोग किया जाता है।

पुनश्च: इसके अलावा अगर आपको पचाने की जरूरत है तो आप अपनी सेवा के भीतर $ rootScope को भी इंजेक्ट कर सकते हैं।


2
धन्यवाद। शानदार जवाब। मेरी स्थिति में गहराई से जाने पर, मुद्दा यह है कि मैं सेवा का उपयोग कर रहा हूं क्योंकि मुझे एक सिंगलटन चाहिए। सेवा का उपभोग करने वाला केवल एक नियंत्रक है, लेकिन ऐप जीवनचक्र के दौरान इस नियंत्रक को कई बार त्वरित किया जा सकता है, इसलिए मैं वास्तव में चाहता हूं कि सेवा हमेशा एक ही स्थिति में हो।
SC

वैसे भी कॉलिंग के बारे में $applyया $digest$ rootScope के बारे में स्पष्टीकरण मुझे पूरी तरह से समझ में आता है।
SC

1
मैं अभी भी इसे परीक्षण के लिए एक सेवा में अलग रखूंगा।
ब्लूहल्लु

यदि कार्यक्षमता नियंत्रक के एक उदाहरण के लिए विशिष्ट है, तो आप किसी सेवा को कार्यान्वित करना छोड़ सकते हैं, लेकिन अन्यथा आप उन उदाहरणों के बीच राज्य साझा करने की क्षमता का त्याग नहीं करते हैं। इसके अलावा, सिर्फ इसलिए कि आज एक ही प्रकार का नियंत्रक है, इसका मतलब यह नहीं है कि एक अलग नियंत्रक नहीं होगा जो कल कार्यक्षमता का लाभ उठा सकता है। इसके अतिरिक्त, एक सेवा नियंत्रक को ब्लोटिंग से बचा सकती है। तो यह इतना सवाल नहीं है कि क्या कोई एकल नियंत्रक है, लेकिन यह है कि कार्यक्षमता क्या है।
निक

9

हाँ। जब आप इसे इनिशियलाइज़ करते हैं तो आप $ स्कोप को सर्विस में पास कर सकते हैं। सर्विस कंस्ट्रक्टर में आप स्कोप को कुछ इस तरह से असाइन कर सकते हैं। _ स्पेस और फिर सर्विस के दायरे को देखें!

angular.module('blah').controller('BlahCtrl', function($scope, BlahService) {

    $scope.someVar = 4;

    $scope.blahService = new blahService($scope);

});

angular.module('blah').factory('blahService', function() {

    //constructor
    function blahService(scope) {
        this._scope = scope;

        this._someFunction()
    }

    //wherever you'd reference the scope
    blahService.prototype._someFunction = function() {

        this._scope['someVar'] = 5;

    }

    return blahService;

});

1
+1, हालांकि, मैं प्रत्येक नियंत्रक को स्वचालित रूप से जानने का एक तरीका देखना चाहता हूं $scopeजब भी दिया गया नियंत्रक सेवा को इंजेक्ट करता है - ताकि सेवा पर एक विधि को कॉल न करना पड़े और $scopeइसे मैन्युअल रूप से पास करना पड़े ।
कोड़ी

2
@ मुझे इस बात की सलाह नहीं है कि यह डिपेंडेंसी इंजेक्शन के विरोधाभासी है
कोल्डस्टार

सहमत, मुझे नीचे शूटिंग के लिए +1! शायद कसाई डीआईपी भी - मैं बेमानी होने के जोखिम पर कहूंगा।
कोडी

आप यहां कारखानों के साथ सेवाओं का मिश्रण कर रहे हैं। यह समाधान एक कारखाने का उपयोग करता है, जो एक सेवा से भिन्न होता है। मुख्य अंतर यह है कि एक सेवा एक (एकल) वस्तु लौटाती है। जबकि एक फैक्ट्री एक फंक्शन लौटाती है, जिसे तुरंत ( new MyFunction()) किया जा सकता है । सवाल एक सेवा के बारे में था, जहां कॉलिंग newएक विकल्प नहीं है।
करवापल्लो

@ करवल्पलो गुड पॉइंट। एक काउंटर बिंदु के रूप में मेरा मानना ​​है कि कोणीय सेवाएं किसी कारखाने, सेवा और प्रदाता (एनजी-वाट) को संदर्भित करती हैं?
user12121234

6

मेरा व्यक्तिगत रूप से मानना ​​है कि $scopeसेवा में पास होना एक बुरा विचार है , क्योंकि यह एक थोड़े गोलाकार संदर्भ बनाता है: नियंत्रक सेवा पर निर्भर करता है और सेवा नियंत्रक के दायरे पर निर्भर करती है।

संबंधों के मामले में भ्रमित होने के शीर्ष पर, इस तरह की चीजें कचरे के संग्रहकर्ता के रास्ते में समाप्त हो जाती हैं।

मेरा पसंदीदा तरीका नियंत्रक क्षेत्र में एक डोमेन ऑब्जेक्ट डालना है और उस सेवा को पास करना है। इस तरह यह सेवा इस बात पर ध्यान दिए बिना काम करती है कि इसका उपयोग किसी कंट्रोलर के अंदर किया गया है या भविष्य में किसी अन्य सेवा के अंदर।

उदाहरण के लिए, यदि किसी सरणी से सेवा को पुश करना है और तत्वों को पॉप करना है errors, तो मेरा कोड होगा:

var errors = [];
$scope.errors = errors;
$scope.myService = new MyService(errors);

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

मैं कभी भी प्रसारण, $applyऔर / या इसी तरह की चीजों का उपयोग नहीं करना चाहूंगा , क्योंकि अच्छे OO- प्रथाओं को हमेशा जो भी कोणीय-जादूगर होगा ट्रम्प करेगा।


1
क्या इस कोड से इस पर कोई फर्क पड़ता है ?:$scope.errors = []; $scope.myService = new MyService($scope.errors);
सोल्डप्लाटा साकेतोस

@SoldeplataSaketos - हाँ, यह करता है। errorsस्वतंत्र रूप से रहता है $scope। यही इस उत्तर का पूरा बिंदु है। Pls मुझे पाठ में दिए गए लिंक की जाँच करें। चीयर्स।
मार्को फॉस्टिनेली

1
यदि मैं सही ढंग से समझता हूं कि आपका कोड $scope.errorsइंगित कर रहा है var errors, और चर त्रुटियां मुझे बेमानी लगती हैं, क्योंकि यह सिर्फ एक अन्य सूचक है। इसी तरह की स्थिति के बारे में मैं सोच सकता हूं और यह स्पष्ट रूप से बेमानी है कि यह कोड का टुकड़ा है const errors = errors2 = errors3 = []; $scope.errors = errors;:। क्या आप सहमत हैं कि आपके द्वारा प्रदान किए गए कोड के केवल टुकड़े से ऐसा लगता है कि var errors = []यह बेमानी है?
सोल्डप्लाटा साकेतोस

नहीं यह नहीं। मैं खुद को शब्द से दोहराता हूं: errorsस्वतंत्र रूप से रहता है $scope। आपको यह समझने की आवश्यकता है कि डोमेन ऑब्जेक्ट क्या है, साथ ही साथ varअसाइनमेंट क्या है। यदि मैंने जो लिंक प्रदान किया है वह पर्याप्त नहीं है, तो बहुत सारी अन्य सामग्री उपलब्ध है।
मार्को फौस्टिनेली

खैर, यह पूरी तरह से कार्य के कार्यान्वयन पर निर्भर करेगा MyService(errors)। मेरी समझ में, सेवा को पैरामीटर के आधार पर एक लॉगिंग सरणी उत्पन्न करना चाहिए (जो इस मामले में एक सूचक है)। मेरे लिए यह एक बुरा पैटर्न है, क्योंकि सेवा कोणीय में एकल हैं। यदि सेवा के कार्यान्वयन को अच्छी तरह से क्रमादेशित किया गया है, तो इसे एक आंतरिक चर (एक सिंगलटन होने के लिए रखने के लिए) में सरणी उत्पन्न करनी चाहिए। इसलिए, सेवा के बाहर चर को शुरू करने का कोई मतलब नहीं है।
सोल्डप्लाटा साकेतोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.