问题
I followed the Angular docs to create my Service and saw an error message
http://docs.angularjs.org/error/$injector:unpr?p0=$scopeProvider%20%3C-%20$scope%20%3C-%20$users
This is my code:
var angularApp = angular.module("myApp", []);
angularApp.run(function($http) {
$http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
$http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});
angularApp.service('$users', function($scope, $http, $cookie, $window) {
// need to instantiate the service
var newUsersServiceInstance;
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
$scope.user // = User.get({userId:123});
$scope.getUser = function(id, s) {
$scope.user = User.get({"userId": id}, s, e);
}
$scope.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
// need to return the instance
return newUsersServiceInstance;
});
angularApp.controller('passwordController', ['$scope', '$users', function($scope, $users) {
$scope.changePasswordForm = function() {
$users.changePassword(
$.param($scope.data),
function(data, xhr) {
console.log(data);
},
function(data, xhr) {
console.log(data);
// error callback
$scope.errors = data.errors;
})
}
$scope.debug = function () {
console.log($scope);
}
}]);
I am not sure where I have gone wrong.
My new code after taking into account everybody's answer. Same error.
var angularApp = angular.module("myApp", []);
angularApp.run(function($http) {
$http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
$http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});
angularApp.service('$users', function($http, $cookie, $window) {
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
this.user // = User.get({userId:123});
this.getUser = function(id, s) {
this.user = User.get({"userId": id}, s, e);
}
this.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
return this;
});
angularApp.controller('passwordController', ['$scope', '$users', function($scope, $users) {
$scope.changePasswordForm = function() {
$users.changePassword(
$.param($scope.data),
function(data, xhr) {
console.log(data);
},
function(data, xhr) {
console.log(data);
// error callback
$scope.errors = data.errors;
})
}
$scope.debug = function () {
console.log($scope);
}
}]);
Even after changing to use factory I see the same errors.
var angularApp = angular.module("myApp", []);
angularApp.run(function($http) {
$http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
$http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});
angularApp.factory('$users', function($resource, $http, $cookie, $window) {
// need to instantiate the service
var newUsersServiceInstance = {};
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
newUsersServiceInstance.user // = User.get({userId:123});
newUsersServiceInstance.getUser = function(id, s) {
newUsersServiceInstance.user = User.get({"userId": id}, s, e);
}
newUsersServiceInstance.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
// need to return the instance
return newUsersServiceInstance;
});
angularApp.controller('passwordController', ['$scope', '$users', function($scope, $users) {
$scope.changePasswordForm = function() {
$users.changePassword(
$.param($scope.data),
function(data, xhr) {
console.log(data);
},
function(data, xhr) {
console.log(data);
// error callback
$scope.errors = data.errors;
})
}
$scope.debug = function () {
console.log($scope);
}
}]);
回答1:
When you use .service
, the function you pass in is invoked as a constructor function. You should not return an instance, try something like this:
angularApp.service('$users', function() {
this.field1 = "something";
this.method1 = function(){
}
//more fields
});
You return an instance only when you use .factory
method. I don't see the point why you need to inject $scope into service function because service is designed to be a reusable component. In your case, you should get rid of $scope. Refactor the code like this:
angularApp.factory('$users', function($resource, $http, $cookie, $window) {//Declare $resource dependency
// need to instantiate the service
var newUsersServiceInstance;
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
newUsersServiceInstance.user; // = User.get({userId:123});
newUsersServiceInstance.getUser = function(id, s) {
newUsersServiceInstance.user = User.get({"userId": id}, s, e);
}
newUsersServiceInstance.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
// need to return the instance
return newUsersServiceInstance;
});
You also have to declare dependency with ngResource, ngCookies if you need to inject them into your factory function.
var angularApp = angular.module("myApp", ['ngResource','ngCookies']);
And don't forget to add:
<script src="angular-resource.js"></script>
<script src="angular-cookies.js"></script>
If you use a CDN, you could add:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.js"> </script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-cookies.js"> </script>
回答2:
There are two ways to write service.
A) use .factory
B) use .service
If the service uses $resource
, then inside the module, you need to require ngResource
, download and add the angular-resource.js
accordingly.
To use ngResource
,
var angularApp = angular.module("myApp", ['ngResource']);
for A)
angularApp.factory('$users', function($resource, $http) {
// need to instantiate the service
var newUsersServiceInstance = {};
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
newUsersServiceInstance.user // = User.get({userId:123});
newUsersServiceInstance.getUser = function(id, s) {
newUsersServiceInstance.user = User.get({"userId": id}, s, e);
}
newUsersServiceInstance.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
// need to return the instance
return newUsersServiceInstance;
});
for B)
angularApp.service('$users', function($resource, $http) {
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
this.user // = User.get({userId:123});
this.getUser = function(id, s) {
this.user = User.get({"userId": id}, s, e);
}
this.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
});
I chose B. Less lines to write.
回答3:
Services don't have $scope
, you can access $rootScope
if needed but it looks like you just want to return an object with all of the functions you want to use.
angularApp.factory('$users', function($http, $cookie, $window) {
// need to instantiate the service
var newUsersServiceInstance = {};
// upper case is resource
var User = $resource('/user/:userId', {userId:'@id'});
var MyPassword = $resource('/mypasswords/new');
// lower case is instance you tend to want the instance
// to be binded to the controller's scope
newUsersServiceInstance.user // = User.get({userId:123});
newUsersServiceInstance.getUser = function(id, s) {
newUsersServiceInstance.user = User.get({"userId": id}, s, e);
}
newUsersServiceInstance.changePassword = function(data, s, e) {
MyPassword.post(data, s, e);
}
// need to return the instance
return newUsersServiceInstance;
});
回答4:
You might get rid of $scope
It doesn't go there :P.
$scope
is a value used in conjunction with controllers.
I'd recommend making your service something like:
angularApp.factory('$users', function($http) {
var userService = {activeUser:{name:'anonymous'}};
return angular.extend(userService,
{
getUser: function(id){
return $http.get('/user/'+id).then(function(response){
userService.activeUser = response.data;
return userService.activeUser;
});
},
changePassword: function(data,se,e){
return $http.post(...)
}
}
);
});
回答5:
As states in Angular docs: $injector:unpr (Unknown Provider)
Attempting to inject a scope object into anything that's not a controller or a directive, for example a service, will throw an Unknown provider: $scopeProvider <- $scope error. This might happen if one mistakenly registers a controller as a service
angular.module('myModule', [])
.service('MyController', ['$scope', function($scope) {
// This controller throws an unknown provider error because
// a scope object cannot be injected into a service.
}]);
来源:https://stackoverflow.com/questions/21212444/unknown-provider-error-in-angular-app