O $scopeque você vê sendo injetado nos controladores não é um serviço (como o resto das coisas injetáveis), mas é um objeto Scope. Muitos objetos de escopo podem ser criados (geralmente herdando prototipicamente de um escopo pai). A raiz de todos os escopos é o $rootScopee você pode criar um novo escopo filho usando o $new()método de qualquer escopo (incluindo o $rootScope).
O objetivo de um Escopo é "unir" a apresentação e a lógica de negócios de seu aplicativo. Não faz muito sentido passar um $scopepara um serviço.
Serviços são objetos singleton usados (entre outras coisas) para compartilhar dados (por exemplo, entre vários controladores) e geralmente encapsulam pedaços de código reutilizáveis (uma vez que podem ser injetados e oferecer seus "serviços" em qualquer parte de seu aplicativo que precise deles: controladores, diretivas, filtros, outros serviços, etc.).
Tenho certeza de que várias abordagens funcionariam para você. Uma é a seguinte:
como o StudentServiceé responsável por lidar com os dados dos alunos, você pode StudentServicemanter uma matriz de alunos e deixá-la "compartilhá-la" com quem estiver interessado (por exemplo, o seu $scope). Isso faz ainda mais sentido, se houver outras visualizações / controladores / filtros / serviços que precisam ter acesso a essas informações (se não houver nenhuma agora, não se surpreenda se elas começarem a aparecer logo).
Cada vez que um novo aluno é adicionado (usando o save()método do serviço ), a própria matriz de alunos do serviço será atualizada e todos os outros compartilhamentos de objetos dessa matriz também serão atualizados automaticamente.
Com base na abordagem descrita acima, seu código pode ser assim:
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.
});
};
}
]);
Uma coisa que você deve ter cuidado ao usar essa abordagem é nunca reatribuir o array do serviço, porque então quaisquer outros componentes (por exemplo, escopos) ainda farão referência ao array original e seu aplicativo será interrompido.
Por exemplo, para limpar a matriz em StudentService:
/* DON'T DO THAT */
var clear = function () { students = []; }
/* DO THIS INSTEAD */
var clear = function () { students.splice(0, students.length); }
Veja, também, esta pequena demonstração .
LITTLE UPDATE:
Algumas palavras para evitar a confusão que pode surgir ao falar sobre o uso de um serviço, mas não criá-lo com a service()função.
Citando os documentos em$provide :
Um serviço Angular é um objeto singleton criado por uma fábrica de serviços . Essas fábricas de serviços são funções que, por sua vez, são criadas por um provedor de serviços . Os provedores de serviços são funções construtoras. Quando instanciados, eles devem conter uma propriedade chamada $get, que contém a função de fábrica de serviço .
[...]
... o $provideserviço tem métodos auxiliares adicionais para registrar serviços sem especificar um provedor:
- provedor (provedor) - registra um provedor de serviços com o $ injetor
- constante (obj) - registra um valor / objeto que pode ser acessado por provedores e serviços.
- valor (obj) - registra um valor / objeto que só pode ser acessado por serviços, não por provedores.
- factory (fn) - registra uma função de fábrica de serviço, fn, que será empacotada em um objeto de provedor de serviço, cuja propriedade $ get conterá a função de fábrica fornecida.
- serviço (classe) - registra uma função construtora, classe que será envolvida em um objeto de provedor de serviço, cuja propriedade $ get instanciará um novo objeto usando a função construtora fornecida.
Basicamente, o que ele diz é que todo serviço Angular é registrado usando $provide.provider(), mas existem métodos de "atalho" para serviços mais simples (dois dos quais são service()e factory()).
Tudo se resume a um serviço, então não faz muita diferença o método que você usa (contanto que os requisitos para seu serviço possam ser cobertos por esse método).
BTW, providervs servicevs factoryé um dos conceitos mais confusos para os novatos do Angular, mas felizmente existem muitos recursos (aqui no SO) para tornar as coisas mais fáceis. (Basta pesquisar.)
(Espero que isso esclareça - me avise se não resolver).