$scope
कि आप नियंत्रकों में इंजेक्ट किया जा रहा देखें कुछ सेवा (इंजेक्शन सामान के बाकी की तरह) नहीं है, लेकिन एक स्कोप वस्तु है। कई स्कोप ऑब्जेक्ट्स बनाए जा सकते हैं (आमतौर पर प्रोटोटाइप मूल रूप से पेरेंट स्कोप से विरासत में मिले हैं)। सभी स्कोप की जड़ है $rootScope
और आप $new()
किसी भी दायरे (सहित $rootScope
) की विधि का उपयोग करके एक नया चाइल्ड-स्कोप बना सकते हैं ।
एक स्कोप का उद्देश्य प्रस्तुति और आपके ऐप के व्यापारिक तर्क को "एक साथ गोंद" करना है। यह $scope
एक सेवा में पारित करने के लिए बहुत मतलब नहीं है ।
सेवाएं डेटा साझा करने के लिए (अन्य नियंत्रकों के बीच) के रूप में उपयोग की जाने वाली सिंगलटन ऑब्जेक्ट्स हैं (उदाहरण के लिए कई नियंत्रकों के बीच) और आमतौर पर कोड के पुन: प्रयोज्य टुकड़ों को एन्कैप्सुलेट करते हैं (क्योंकि उन्हें आपके ऐप के किसी भी हिस्से में "सेवाओं" को इंजेक्ट किया जा सकता है और उनकी आवश्यकता होती है: नियंत्रकों निर्देश, फिल्टर, अन्य सेवाएं आदि)।
मुझे यकीन है, विभिन्न दृष्टिकोण आपके लिए काम करेंगे। एक यह है:
चूंकि StudentService
छात्र डेटा से निपटने के लिए प्रभारी है, तो आप StudentService
छात्रों की एक सरणी रख सकते हैं और जो कोई भी दिलचस्पी ले सकता है, उसे "शेयर" करें (जैसे कि आपका $scope
)। यह और भी अधिक समझ में आता है, अगर अन्य विचार / नियंत्रक / फ़िल्टर / सेवाएं हैं जिनकी उस जानकारी तक पहुंच की आवश्यकता है (यदि अभी कोई अधिकार नहीं है, तो आश्चर्यचकित न हों यदि वे जल्द ही पॉप अप करना शुरू कर दें)।
हर बार एक नया छात्र जोड़ा जाता है (सेवा की save()
विधि का उपयोग करके ), सेवा के छात्रों की अपनी सरणी को अपडेट किया जाएगा और उस सरणी को साझा करने वाली प्रत्येक अन्य वस्तु स्वचालित रूप से भी अपडेट हो जाएगी।
ऊपर वर्णित दृष्टिकोण के आधार पर, आपका कोड इस तरह दिख सकता है:
angular.
module('cfd', []).
factory('StudentService', ['$http', '$q', function ($http, $q) {
var path = 'data/people/students.json';
var students = [];
// In the real app, instead of just updating the students array
// (which will be probably already done from the controller)
// this method should send the student data to the server and
// wait for a response.
// This method returns a promise to emulate what would happen
// when actually communicating with the server.
var save = function (student) {
if (student.id === null) {
students.push(student);
} else {
for (var i = 0; i < students.length; i++) {
if (students[i].id === student.id) {
students[i] = student;
break;
}
}
}
return $q.resolve(student);
};
// Populate the students array with students from the server.
$http.get(path).then(function (response) {
response.data.forEach(function (student) {
students.push(student);
});
});
return {
students: students,
save: save
};
}]).
controller('someCtrl', ['$scope', 'StudentService',
function ($scope, StudentService) {
$scope.students = StudentService.students;
$scope.saveStudent = function (student) {
// Do some $scope-specific stuff...
// Do the actual saving using the StudentService.
// Once the operation is completed, the $scope's `students`
// array will be automatically updated, since it references
// the StudentService's `students` array.
StudentService.save(student).then(function () {
// Do some more $scope-specific stuff,
// e.g. show a notification.
}, function (err) {
// Handle the error.
});
};
}
]);
इस दृष्टिकोण का उपयोग करते समय आपको एक बात ध्यान रखनी चाहिए कि सेवा के एरे को फिर से असाइन न करें, क्योंकि तब कोई भी अन्य घटक (जैसे स्कोप) अभी भी मूल एरे को संदर्भित करेगा और आपका ऐप टूट जाएगा।
उदाहरण के लिए StudentService
:
/* DON'T DO THAT */
var clear = function () { students = []; }
/* DO THIS INSTEAD */
var clear = function () { students.splice(0, students.length); }
यह लघु डेमो भी देखें ।
थोड़ा अद्यतन:
किसी सेवा का उपयोग करने के बारे में बात करते समय उत्पन्न होने वाले भ्रम से बचने के लिए कुछ शब्द, लेकिन इसे service()
फ़ंक्शन के साथ नहीं बनाया जा सकता है ।
डॉक्स को$provide
उद्धृत करना :
एक कोणीय सेवा एक सेवा कारखाने द्वारा बनाई गई एक सिंगलटन ऑब्जेक्ट है । ये सेवा कारखाने ऐसे कार्य हैं जो बदले में, एक सेवा प्रदाता द्वारा बनाए जाते हैं । सेवा प्रदाताओं निर्माता कार्य हैं। जब तात्कालिक रूप से उन्हें एक संपत्ति कहा जाना चाहिए $get
, जो सेवा कारखाने का कार्य रखती है ।
[...]
... $provide
सेवा में एक प्रदाता को निर्दिष्ट किए बिना सेवाओं को पंजीकृत करने के लिए अतिरिक्त सहायक विधियाँ हैं:
- प्रदाता (प्रदाता) - $ इंजेक्टर के साथ एक सेवा प्रदाता को पंजीकृत करता है
- स्थिरांक (obj) - एक मूल्य / वस्तु को पंजीकृत करता है जिसे प्रदाताओं और सेवाओं द्वारा पहुँचा जा सकता है।
- मूल्य (obj) - एक मूल्य / वस्तु को पंजीकृत करता है जिसे केवल सेवाओं द्वारा पहुँचा जा सकता है, प्रदाताओं द्वारा नहीं।
- factory (fn) - एक सेवा कारखाने के कार्य को पंजीकृत करता है, fn, जिसे एक सेवा प्रदाता वस्तु में लपेटा जाएगा, जिसकी $ get property में दिए गए factory function होंगे।
- सेवा (वर्ग) - एक कंस्ट्रक्टर फ़ंक्शन को पंजीकृत करता है, वह वर्ग जो एक सेवा प्रदाता ऑब्जेक्ट में लपेटा जाएगा, जिसकी $ प्रॉपर्टी दी गई कंस्ट्रक्टर फ़ंक्शन का उपयोग करके एक नई ऑब्जेक्ट को तुरंत हटा देगी।
असल में, यह क्या कहता है कि प्रत्येक कोणीय सेवा का उपयोग करके पंजीकृत किया जाता है $provide.provider()
, लेकिन सरल सेवाओं के लिए "शॉर्टकट" विधियां हैं (जिनमें से दो हैं service()
और factory()
)।
यह सब "एक सेवा के लिए" उबलता है, इसलिए इससे बहुत फर्क नहीं पड़ता है कि आप किस विधि का उपयोग करते हैं (जब तक कि आपकी सेवा की आवश्यकताओं को उस पद्धति द्वारा कवर किया जा सकता है)।
बीटीडब्ल्यू, provider
बनाम service
बनाम factory
एंगुलर नई-कॉमर्स के लिए सबसे भ्रामक अवधारणाओं में से एक है, लेकिन सौभाग्य से चीजों को आसान बनाने के लिए बहुत सारे संसाधन (यहां एसओ पर) हैं। (बस आसपास खोज करें।)
(मुझे आशा है कि इसे साफ कर दिया जाएगा - मुझे बताएं कि क्या यह नहीं है।)