gpt4 book ai didi

angularjs - 将 $scope 注入(inject) angular.service 函数()

转载 作者:行者123 更新时间:2023-12-03 04:44:32 24 4
gpt4 key购买 nike

我有一项服务:

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 is not defined 。所以(对我来说)合乎逻辑的步骤是为 save() 提供 $scope ,因此我还必须将其提供/注入(inject)到 service 。所以如果我这样做:

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

我收到以下错误:

Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- StudentService

错误中的链接(哇,太棒了!)让我知道它与注入(inject)器相关,并且可能与 js 文件的声明顺序有关。我尝试在 index.html 中重新排序它们,但我认为这是更简单的事情,比如我注入(inject)它们的方式。

使用 Angular-UI 和 Angular-UI-Router

最佳答案

您看到注入(inject)到 Controller 中的 $scope 不是某种服务(就像其他可注入(inject)的东西一样),而是一个 Scope 对象。可以创建许多范围对象(通常是从父范围继承的原型(prototype))。所有作用域的根是 $rootScope,您可以使用任何作用域(包括 $rootScope)的 $new() 方法创建新的子作用域)。

范围的目的是将应用程序的演示文稿和业务逻辑“粘合在一起”。将 $scope 传递到服务中没有多大意义。

服务是单例对象,用于(除其他外)共享数据(例如在多个 Controller 之间),并且通常封装可重用的代码片段(因为它们可以注入(inject)并在应用程序需要它们的任何部分提供“服务” : Controller 、指令、过滤器、其他服务等)。

我确信,多种方法都适合您。其一是这样的:
由于 StudentService 负责处理学生数据,因此您可以让 StudentService 保留一组学生,并让它与任何可能感兴趣的人“共享”(例如,您的$scope)。如果有其他 View / Controller /过滤器/服务需要访问该信息(如果现在没有,如果它们很快就会开始出现,请不要感到惊讶),这更有意义。
每次添加新学生(使用服务的 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); }

另请参阅此 short demo

<小时/>

小更新:

几句话以避免在谈论使用服务但不使用 service() 函数创建服务时可能出现的困惑。

引用docs on $provide :

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())。
这一切都“归结为”服务,因此使用哪种方法没有太大区别(只要该方法可以满足您的服务要求)。

顺便说一句,provider vs service vs factory 是 Angular 新手最容易混淆的概念之一,但幸运的是,有很多资源(此处为 SO)使事情变得更容易。 (只需四处搜索即可。)

(我希望能够解决这个问题 - 如果没有,请告诉我。)

关于angularjs - 将 $scope 注入(inject) angular.service 函数(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22898927/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com