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 译者:赵望野 徐飞 何鹏飞
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android IPC进程间通讯机制
- Android学习笔记(二九):嵌入浏览器
- android之定时器AlarmManager
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- axis备忘
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 异步流程控制:7 行代码学会 co 模块
- JavaScript拆分字符串时产生空字符的原因
- IE8开发人员工具教程(二)
- 在flex中执行一个javascript方法的简单方式
- Flex结合JavaScript读取本地路径的方法
- PowerShell中执行Javascript的方法示例
- javascript asp教程第六课-- response方法
- javascript asp教程More About Recordsets
- javascript asp教程第十二课---session对象