$scope
Eğer denetleyicileri enjekte ediliyor gördüklerim (enjektabl şeyler geri kalanı gibi) bazı hizmet değil, ama bir Kapsam nesnesidir. Birçok kapsam nesnesi oluşturulabilir (genellikle prototip olarak bir üst kapsamdan miras alınır). Tüm kapsamların kökü, herhangi bir kapsamın (dahil ) yöntemini $rootScope
kullanarak yeni bir alt kapsam oluşturabilirsiniz .$new()
$rootScope
Kapsamın amacı, uygulamanızın sunumunu ve iş mantığını "birbirine yapıştırmaktır". $scope
Bir hizmete geçmek pek mantıklı değil .
Hizmetler, verileri paylaşmak için (diğer şeylerin yanı sıra) kullanılan tek nesnelerdir (örneğin, birkaç denetleyici arasında) ve genellikle yeniden kullanılabilir kod parçalarını kapsüller (çünkü bunlar uygulamanızın bunlara ihtiyaç duyan herhangi bir bölümünde enjekte edilebilir ve "hizmetlerini" sunarlar: denetleyiciler, yönergeler, filtreler, diğer hizmetler vb.).
Eminim, çeşitli yaklaşımlar sizin için işe yarar. Biri şudur: Öğrenci verileriyle ilgilenmekten sorumlu
olduğu için StudentService
, StudentService
bir dizi öğrenciyi tutabilir ve ilgilenebilecek kişilerle (örneğin sizin $scope
) "paylaşmasına" izin verebilirsiniz . Bu bilgiye erişmesi gereken başka görünümler / denetleyiciler / filtreler / hizmetler varsa bu daha da mantıklıdır (şu anda yoksa, yakında çıkmaya başlarlarsa şaşırmayın).
Her yeni öğrenci eklendiğinde (hizmetin save()
yöntemini kullanarak ), hizmetin kendi öğrenci dizisi güncellenecek ve bu diziyi paylaşan diğer tüm nesneler de otomatik olarak güncellenecektir.
Yukarıda açıklanan yaklaşıma bağlı olarak, kodunuz şöyle görünebilir:
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.
});
};
}
]);
Bu yaklaşımı kullanırken dikkat etmeniz gereken bir şey, hizmet dizisini asla yeniden atamamaktır, çünkü diğer bileşenler (örn. Kapsamlar) yine de orijinal diziye referans veriyor olacak ve uygulamanız bozulacaktır.
Örneğin, diziyi temizlemek için StudentService
:
/* DON'T DO THAT */
var clear = function () { students = []; }
/* DO THIS INSTEAD */
var clear = function () { students.splice(0, students.length); }
Ayrıca bu kısa demoya bakın .
KÜÇÜK GÜNCELLEME:
Bir servisi kullanmaktan bahsederken ortaya çıkabilecek kafa karışıklığını önlemek için birkaç kelime, ancak onu service()
işlevle oluşturmamak .
Dokümanlardan$provide
alıntı yapmak :
Bir Angular hizmet , bir hizmet fabrikası tarafından oluşturulan tek bir nesnedir . Bu hizmet fabrikaları , bir hizmet sağlayıcı tarafından oluşturulan işlevlerdir . Servis sağlayıcıları yapıcı fonksiyonları bulunmaktadır. Örneklendiğinde $get
, hizmet fabrikası işlevini tutan bir özellik içermelidirler .
[...]
... $provide
hizmetin, bir sağlayıcı belirtmeden hizmetleri kaydettirmek için ek yardımcı yöntemleri vardır:
- sağlayıcı (sağlayıcı) - bir hizmet sağlayıcıyı $ enjektör ile kaydeder
- sabit (obj) - sağlayıcılar ve hizmetler tarafından erişilebilen bir değeri / nesneyi kaydeder.
- değer (obj) - sağlayıcılar tarafından değil, yalnızca servisler tarafından erişilebilen bir değeri / nesneyi kaydeder.
- fabrika (fn) - $ get özelliği verilen fabrika işlevini içerecek bir hizmet sağlayıcı nesnesine sarılacak bir hizmet fabrikası işlevi olan fn'yi kaydeder.
- service (sınıf) - $ get özelliği verilen yapıcı işlevini kullanarak yeni bir nesne başlatacak olan bir hizmet sağlayıcı nesnesine sarılacak bir sınıf olan yapıcı işlevini kaydeder.
Temel olarak söylediği, her Angular servisinin kullanılarak kaydedildiği $provide.provider()
, ancak daha basit servisler için "kısayol" metotları olduğu (bunlardan ikisi service()
ve factory()
).
Her şey bir hizmete "kaynar", bu nedenle hangi yöntemi kullandığınız çok fazla fark yaratmaz (hizmetinizin gereksinimleri bu yöntemle karşılanabildiği sürece).
BTW, provider
vs service
vs factory
, Angular'a yeni gelenler için en kafa karıştırıcı kavramlardan biridir, ancak neyse ki işleri kolaylaştırmak için birçok kaynak (burada SO'da) vardır. (Sadece etrafı araştırın.)
(Umarım bu sorunu çözer, yoksa bana haber verin.)