注射$范围成多角服务功能() [英] Injecting $scope into an angular service function()

查看:134
本文介绍了注射$范围成多角服务功能()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务:

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;
          }
        }
      }
    };

但是,当我打电话保存(),我没有访问 $范围,并获得的ReferenceError:$范围没有定义。因此,合乎逻辑的步骤(对我来说),是提供保存()与 $范围,因此我也必须提供/它注入到服务。所以,如果我这样做,像这样:

But when I call save(), I don't have access to the $scope, and get ReferenceError: $scope is not defined. So the logical step (for me), is to provide save() with the $scope, and thus I must also provide/inject it to the service. So if I do that like so:

  .service('StudentService', [ '$http', '$scope',
                      function ($http, $scope) {

我收到以下错误:错误:[$喷油器:unpr]未知提供商:$ scopeProvider< - $范围< - StudentService

错误(哇,这是整洁!)链接让我知道它是喷油器有关,并有可能与js文件中声明的顺序做。我试图在重新排序它们 index.html的,但我认为这是一些更简单的,比如我是他们注射的方式。

The link in the error (wow that is neat!) lets me know it is injector related, and might have to do with order of declaration of the js files. I have tried reordering them in the index.html, but I think it is something more simple, such as the way I am injecting them.

采用了棱角分明的UI和角度-UI-路由器

Using Angular-UI and Angular-UI-Router

推荐答案

$范围,你看到被注入到控制器,是不是有些服务(如的休息注射用的东西),而是一个范围对象。许多范围的对象可以创建(通常是中典型从父范围继承)。所有范围的根是 $ rootScope 键,则可以使用创建一个新的儿童范围 $新的()任何范围的方法(包括 $ rootScope )。

The $scope that you see being injected into controllers is not some service (like the rest of the injectable stuff), but is a Scope object. Many scope objects can be created (usually prototypically inheriting from a parent scope). The root of all scopes is the $rootScope and you can create a new child-scope using the $new() method of any scope (including the $rootScope).

一个范围的目的是为了粘合在一起的presentation和您的应用程序的业务逻辑。它没有多大意义,一个 $范围传递到一个服务。

The purpose of a Scope is to "glue together" the presentation and the business logic of your app. It does not make much sense to pass a $scope into a service.

服务被使用(除其他事项外)共享数据(如多个控制器之间),一般封装code的可重用代码的(因为它们可以被注射,并在您的应用程序的任何部分提供他们的服务的单一对象需要它们:控制器,指令,过滤器,其他服务等)

Services are singleton objects used (among other things) to share data (e.g. among several controllers) and generally encapsulate reusable pieces of code (since they can be injected and offer their "services" in any part of your app that needs them: controllers, directives, filters, other services etc).

我相信,不同的方法会为你工作。一种是这样的:搜索
因为 StudentService 负责处理学生的数据,你可以有 StudentService 保持学生的数组,并让它与谁可能会感兴趣共享它(例如,您 $范围)。这使得更多的意义上说,如果有其他的看法/控制器/过滤器/需要有该信息(如果没有任何的权利,如果他们开始不久突然出现不感到惊讶)接入服务。

每一个新的学生加入(使用该服务的保存()法)时,该服务的本校学生的阵列将被更新和所有其他对象共享的阵列将得到自动更新为好。

I am sure, various approaches would work for you. One is this:
Since the StudentService is in charge of dealing with student data, you can have the StudentService keep an array of students and let it "share" it with whoever might be interested (e.g. your $scope). This makes even more sense, if there are other views/controllers/filters/services that need to have access to that info (if there aren't any right now, don't be surprised if they start popping up soon).
Every time a new student is added (using the service's save() method), the service's own array of students will be updated and every other object sharing that array will get automatically updated as well.

根据上述的方法,您的code可能是这样的:

Based on the approach described above, your code could look like this:

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); }

又见这个 短演示

See, also, this short demo.

小更新:

一个几句话,以避免一边谈论使用服务,但不与服务创造它可能出现的混乱()功能。

A few words to avoid the confusion that may arise while talking about using a service, but not creating it with the service() function.

引用的 $在 文档提供

这是角的服务是由服务工厂创建了一个单独的对象。这些服务工厂是,这反过来,由服务提供商创建功能。在服务提供商的构造函数。在初始化它们必须包含一个名为属性 $ GET ,其中包含在服务工厂功能。结果
  [...]结果
  ...在 $提供服务有额外的辅助方法,而不指定提供商注册服务:

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:


      
  • (提供商) - 注册到$喷油器服务提供商

  •   
  • 常数(OBJ) - 寄存器,可以由提供者和服务进行访问的值/对象。

  •   
  • 值(OBJ) - 注册,只能通过服务,而不是供应商进行访问的值/对象。

  •   
  • 工厂(FN) - 注册服务工厂函数,FN,将包裹在一个服务提供者对象,其$获得属性将包含给定的工厂函数。

  •   
  • 服务(类) - 注册一个构造函数,类将被包裹在一个服务提供者对象,其$获取属性将使用给定的构造函数实例化一个新的对象

  •   
  • 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.

基本上,它说的是,每一个角服务使用注册 $ provide.provider(),但也有更简单的服务快捷方式的方法(其中两个是服务()厂())。结果
这一切都归结来服务,所以它不会让你使用哪种方法(只要为你服务的需求可以通过该方法被覆盖)太大的区别。

Basically, what it says is that every Angular service is registered using $provide.provider(), but there are "shortcut" methods for simpler services (two of which are service() and factory()).
It all "boils down" to a service, so it doesn't make much difference which method you use (as long as the requirements for your service can be covered by that method).

BTW,提供商 VS 服务 VS 工厂是对角新来者最容易混淆的概念之一,但幸运的是有大量的资源(这里SO)使事情变得更容易。 (只是四处搜寻。)

BTW, provider vs service vs factory is one of the most confusing concepts for Angular new-comers, but fortunately there are plenty of resources (here on SO) to make things easier. (Just search around.)

(我希望清除它 - 让我知道,如果它不)

(I hope that clears it up - let me know if it doesn't.)

这篇关于注射$范围成多角服务功能()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆