angular.module('cfd') .service('StudentService',[ '$http',function ($http) { // get some data via the $http var path = 'data/people/students.json'; var students = $http.get(path).then(function (resp) { return resp.data; }); //save method create a new student if not already exists //else update the existing object this.save = function (student) { if (student.id == null) { //if this is new student,add it in students array $scope.students.push(student); } else { //for existing student,find this student using id //and update it. for (i in students) { if (students[i].id == student.id) { students[i] = student; } } } };
但是当我调用save(),我没有访问$ scope,并获得ReferenceError:$ scope没有定义。所以逻辑步骤(对我来说)是为$ scope提供save(),因此我也必须提供/注入到服务。所以如果我这样做:
.service('StudentService','$scope',function ($http,$scope) {
我得到以下错误:
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <-
StudentService
错误中的链接(哇,那是整洁!)让我知道它是与注射器相关,并可能与声明的js文件的顺序。我已经尝试在index.html中重新排序他们,但我认为这是更简单的,如我注射他们的方式。
使用Angular-UI和Angular-UI-Router
范围的目的是“粘合在一起”您的应用程序的演示和业务逻辑。将$ scope传递到服务没有什么意义。
服务是使用(以及其他方式)共享数据(例如在多个控制器之间)并且通常封装可重用代码片段的单例对象(因为它们可以被注入并且在应用的任何部分提供他们需要它们的“服务”:控制器,指令,过滤器,其他服务等)。
我相信,各种方法会为你工作。一个是:
由于StudentService负责处理学生数据,因此您可以让StudentService保存一组学生,并让其与任何可能感兴趣的人(例如您的$范围)“共享”。这更有意义,如果有其他视图/控制器/过滤器/服务,需要访问该信息(如果现在没有任何权利,不要惊讶,如果他们开始弹出很快)。
每次添加一个新学生(使用服务的save()方法),服务自己的学生数组将被更新,并且共享该数组的每个其他对象也将自动更新。
angular.module('cfd',[]) .factory('StudentService',['$http',function ($http) { 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 */ 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; } } } }; /* Populate the students array with students from the server */ $http.get(path).success(function (data) { 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 StudentService.save(student); // The $scope's `students` array will be automatically updated // since it references the StudentService's `students` array // Do some more $scope-specific stuff,// e.g. show a notification }; } ]);
使用这种方法时,你应该注意的一点是不要重新分配服务的数组,因为任何其他组件(例如范围)将仍然引用原始数组,你的应用程序将中断。
例如。清除StudentService中的数组:
/* DON'T DO THAT */ var clear = function () { students = []; } /* DO THIS INSTEAD */ var clear = function () { students.splice(0,students.length); }
另见,short demo。
小数更新:
几个字,以避免在谈论使用服务时可能出现的混乱,但不是使用service()函数创建它。
An Angular service is a singleton object created by a service factory. These service factories are functions which,in turn,are created by a service provider. The service providers are constructor functions. When instantiated they must contain a property called
$get
,which holds the service factory function.
[…]
…the$provide
service has additional helper methods to register services without specifying a provider:
- provider(provider) – registers a service provider with the $injector
- constant(obj) – registers a value/object that can be accessed by providers and services.
- value(obj) – registers a value/object that can only be accessed by services,not providers.
- factory(fn) – registers a service factory function,fn,that will be wrapped in a service provider object,whose $get property will contain the given factory function.
- service(class) – registers a constructor function,class that will be wrapped in a service provider object,whose $get property will instantiate a new object using the given constructor function.
基本上,它说的是每个Angular服务使用$ provide.provider()注册,但是有更简单的服务(其中两个是service()和factory())的“快捷方式”方法。
这一切都“归结”到一个服务,所以它没有什么区别使用哪种方法(只要你的服务的要求可以由该方法覆盖)。
BTW,提供商vs服务vs工厂是Angular新手的最混乱的概念之一,但幸运的是有很多资源(这里是SO),使事情更容易。 (只搜索。)
(我希望清除它 – 让我知道,如果它不)。