您的位置:首页 > Web前端 > AngularJS

AngularJS(二)——使用AngularJS自定义service

2015-06-08 13:12 477 查看
按照
MVC
模式的设计原则,
controller
应该尽可能保持短小精悍。同样,在AngularJS中,不提倡在
controller
中进行
DOM
操作和数据操作。先来看一个臃肿的、难以维护的
controller
var app = angular.module('APPModule', []);
app.controller('MainController', function($scope) {
$scope.shouldShowLogin = true;
$scope.showLogin = function() {
$scope.shouldShowLogin =!$scope.shouldShowLogin;
};
$scope.clickButton = function() {
$('#btnspan').html('Clicked');
};
$scope.onLogin = function(user) {
$http({
method: 'POST',
url: '/login',
data: {
user: user
}
}).success(function(data) {
//Some Actions
});
};
});
初学者总是倾向于写出这种代码,过多的逻辑和前后台交互被放到了本应用来渲染数据的
$scope
对象上。更加优雅的方法是通过使用
service
directive
使
controller
更轻量,更易于维护。下面来看看如何自定义并使用
service
,至于
directive
,我们之后再谈。

1. 创建并使用自定义service

1. 通过
factory()
创建自定义service
var app = angular.module('APPModule', []);
app.factory('UserService', [ //制定自定义service名为UserService
'$http',
function($http) {
var runLogin = function(user) {
$http({
method: 'POST',
url: '/login',
data: {
user: user
}
}).success(function(data) {
//Some Actions
});
};

return {
runLogin: runLogin
};
}
]);
不难发现,如此声明自定义的 service 后,我们将之前臃肿的
controller
中的登录逻辑放到了 UserService中,代码马上变得逼格十足。2. 使用自定义service
app.controller('MainController', [
'$scope',
'UserService', //在此将自定义的UserService注入
function($scope, UserService) {
$scope.onLogin = function(user) {
//调用UserService的runLogin方法进行登录
UserService.runLogin(user);
};
}
]);
这里的UserService就是我们的自定义
service
,在
controller
初始化时注入,即可使用其中的值和方法了,是不是十分方便?注意一点,在自定义服务之前注入所有的AngularJS内置服务,是约定俗称的规则,比如这里我们就是先注入内置的
$scope
,再注入自定义的UserService。如果自定义的
service
和使用它的
controller
不在同一个
module
中,需要将
service
所处的
module
注入到
controller
所处的
module
中:
var serviceModule = angular.module('ServiceModule', []);
serviceModule.factory('UserService', [
'$http',
function($http) {
… //与之前UserService相同
}
]);

//将service所处的module注入到controller所处的module中
var app = angular.module('APPModule', ['ServiceModule']);
app.controller('MainController', [
'$scope',
'UserService',
function($scope, UserService) {
… //与之前controller相同
}
]);

2. 创建自定义service的其他方式

factory()
方法是用来创建服务的最常见的方式之一,除此之外,还有一些其他方式可以创建服务。2.1 使用
service()
service()
这个方法名知道它是用来创建服务的,它允许为服务对象注册一个构造函数:
app.service('ProductService', function($http) {
this.getProductList = function() {
$http({method: 'GET', url: '/api/product'});
};
});
如果使用和
factory()
相同的方式,也可以创建服务:
app.service('ProductService', function($http) {
var getProductList = function() {
$http({method: 'GET', url: '/api/product'});
};

return {
getProductList: getProductList
};
});
读者可根据自己的习惯决定具体使用何种方式。2.2 使用
provider()
app.provider('NameService', {
self: this,
setName: function(name) {
self.name = name;
},
$get: function() {
return {
getName: function() {
return self.name;
}
};
}
});
使用
provider()
创建时,返回的对象中必须有
$get()
属性,其值为一个返回共有函数的函数,如果没有
$get
属性会报错:
Uncaught Error: [$injector:modulerr] Failed to instantiate module exampleApp due to:
Error: [$injector:pget] Provider 'NameService' must define $get factory method.
provider()
创建服务可以在多个应用使用同一个
service
时获得更强的扩展性,通过如下方式对
service
进行扩展:
app.config(function(NameServiceProvider) {
NameServiceProvider.setName('Lucy');
});
其中,NameServiceProvider为对应的服务名(NameService) + Provider组成,通过这一对象可以调用 NameService中的方法,无论该方法有没有被暴露出来。比如,NameService中只暴露出一个
getName
方法,如果直接在
controller
中使用NameService.setName('Lucy')会报错:
TypeError: undefined is not a function
但通过
provider()
,可以为NameService设初始值。2.3 使用
constant()
准确来说,这里要说到的
constant()
和下面要提到的
value()
并不算传统意义上
MVC
中的
service
,为了方便在这一并讲一下。该方法可以将变量值注册为服务,可以使该变量被其他
module
controller
共享,是一种在多个
module
controller
共享数据的方法:
app.constant('ASToken', '12345abcde'); //分别对应'key', 'value'
app.controller('MainController', [
'$scope',
'$log',
'ASToken', //注入constant
function($scope, $log, ASToken) {
//Some Actions
$log.info(ASToken); //12345abcde
}
]);
2.4 使用
value()
constant()
用法十分相似,唯一的区别是,
constant()
可以注入到
config()
中,而
value()
不可以:
app.constant('ASToken', '12345').config(function(ASToken) {
//正常使用
});
app.constant('ASValue', '12345').config(function(ASValue) {
//ASValue在config中无法访问
});
3.AngularJS中的拦截器$provide.decorator():AngularJS中的
$provide
服务提供了在服务实例创建时对其进行拦截的功能,可以在有需求的情况下对服务进行扩展[b]和修改[/b]。不仅可以使用在自定义服务上,也可以对AngularJS的内置服务进行拦截。以拦截2.1中
provider()
创建的UserService为例:
app.config([
'$provide’,
function($provide) {
$provide.decorator('UserService', [
'$delegate',
function($delegate) {
return{
getName: function() {
return $delegate.getName() + ' <-- TheFunction Has Been Decorated.'
},
getAge: function() {
return 18;
}
};
}
]);
}
]);
config()
中,通过
$provide.decorate()
方法拦截UserService,注入的
$delegate
可以调用要拦截的
service
中原本的方法。这里我们通过对UserService 进行拦截,修改了 UserService中的
getName()
方法,并为UserService添加了
getAge()
方法。完。参考资料:《AngularJS 权威教程》 作者:Ari Lerner 译者:赵望野 徐飞 何鹏飞
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息