AngularJS中如何对Controller与Service进行分层设计与编码
初学者的Controller
在我们当接触NG后,如需要通过访问远程的API获取一系列的数据进行显示,通常我的Controller代码会写成下面的样子:
angular.module('demo')
.controller('myCtrl',['$scope','$http', function($scope,$http){
$http.get("xxx")
.success(function(response)
{
$scope.data = response.data;
});
}]);
这样的在功能上是没有问题的,但是会导致Controller除了负担了与View层的$scope变量的初始化和防范定义还需要额外注入http进行远程的数据调用。
如当调用API的代码是会大量被引用、或是API变更时候会导致大面的修改Controller代码。
分离Service
Service层和Controller层的分工
我们将原来全部集中在Controller中代码拆分成两个层面:
- service层:主要负责数据交互和数据处理、处理一些业务领域上的逻辑;
- controller层:主要负责初始化$scope的变量用于传递给view层,并且处理一些页面交互产生的逻辑;
什么情况下需要编写Service
当一个功能是设计远程API调用、数据集、业务领悟复杂逻辑、将会大量重复的运算方法时就可以考虑将代码以service形式注入controller层。
编写Service
将原先的代码从Controller中抽离处理,代码如下:
angular.module('demo')
.service('myService',['$http',function($http){
return {
getData:function(){
return $http.get("xxx");
}
}
}]);
则Controller的代码将会被注入myService用于获取相关的数据
angular.module('demo')
.controller('myCtrl',['$scope','myService', function($scope,$http,myService){
myService.getData().success(function(response)
{
$scope.data = response.data;
});
}]);
基本上这样的代码看上去很不错了,但是我们依旧在Controller层处理了通讯时的回调函数success,这样controller虽然直接依赖http了,但是还是间接的需要处理http。
在Service层处理通讯回调,将业务回调传递给Controller层
这里需要引入deffered将http的通讯级的回调在Service层处理完后,再重新交由controller去处理其他的问题。
angular.module('demo')
.service('myService',['$http','$q',function($http,$q){
return {
getData:function(){
var deferred = $q.defer();
var promise = $http.get("xxx");
promise.then(
// 通讯成功的处理
function(answer){
//在这里可以对返回的数据集做一定的处理,再交由controller进行处理
answer.status = true;
deferred.resolve(answer);
},
// 通讯失败的处理
function(error){
// 可以先对失败的数据集做处理,再交由controller进行处理
error.status = false;
deferred.reject(error);
});
//返回promise对象,交由controller继续处理成功、失败的业务回调
return deferred.promise;
}
}
}]);
相应的在controller中我们也可以进行相关事件的处理,修改代码如下
angular.module('demo')
.controller('myCtrl',['$scope','myService', function($scope,myService){
myService.getData().then(
function(answer){
$scope.data = answer;
},
function(error){
$scope.error = error;
}
);
}]);
这样controller和servic的职业分离,并且controller完全不依赖http而只是依赖service传递的事件和数据。再编写测试代码时,其逻辑也会变得简单。并且多个controller可以调用一个service中相同的方法,而不是通过曾经那种复制的方法来解决。
分层编写代码的最终目的无非就是
- 增加代码的复用性;
- 代码责任简单,不会又做保姆又做司机,可读性强容易理解;
- 编写测试代码的时候容易编写;
- 减少对一些框架和环境插件的依赖;
- 修改逻辑时最小幅度的修改代码
- 数据层发生变更修改Service,UI层有变化则修改Controller。不用担心改controller把service也一起带到沟里的情况发生。
最后的最后
AngularJS在许多框架的设计方面与Java的Spring非常类似,如你有一定的Java基础应该很能理解为赢编写出分层的代码。
原文链接:http://www.jianshu.com/p/1e1aaf0fd30a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
AngularJS中如何对Controller与Service进行分层设计与编码的更多相关文章
- angularjs中provider,factory,service的区别和用法
angularjs中provider,factory,service的区别和用法 都能提供service,但是又有差别 service 第一次被注入时实例化,只实例化一次,整个应用的生命周期中是个单例 ...
- AngularJS中的Provider们:Service和Factory等的区别
引言 看了很多文章可能还是不太说得出AngularJS中的几个创建供应商(provider)的方法(factory(),service(),provider())到底有啥区别,啥时候该用啥,之前一直傻 ...
- angularJS中directive与controller之间的通信
当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...
- [译]AngularJS中几种Providers(Factory, Service, Provider)的区别
原文: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/ 什么是Provider? Angula ...
- AngularJS中Model和Controller传值问题
最近由于工作原因,开始写点前端的东西.前两天刚开始了解AngularJS这门技术,当然,新手免不了会爬坑! 今天分享一篇关于--> 模型传参给Controller的实例: 需求: 具体是 首先 ...
- 八、angularjs 中 filter在controller中的使用--避免多次遍历
filter在html页面的使用司空见惯,比如: filter在controller中使用可以避免多次使用angular.foreach,来进行遍历.例如: 如果使用filter,则会让代码简洁而且明 ...
- AngularJS 中 Provider 的用法及区别
在一个分层良好的 Angular 应用中,Controller 这一层应该很薄.也就是说,应用里大部分的业务逻辑和持久化数据都应该放在 Service 里. 为此,理解 AngularJS 中的几个 ...
- 怎么理解angularjs中的服务?
AngularJS中的服务其实就是提供一种方式抽取共用类库 比如说一些工具类方法,我们传统的做法就是自己写个 utility 类,把相关的工具方法填充到utility里面去,最后把utility类放到 ...
- AngularJS中使用Directive、Controller、Service
AngularJS是一款非常强大的前端MVC框架.同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉. (1)Directive 指令 (2)Controller 控制器 (3)Service ...
随机推荐
- MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 二
本次改动的主要内容是实现MongoDB.Repository对MongoDBRef的支持. MongoDB对一对一,一对多,多对多关系的维护,官方推荐文档嵌入方式,反映到模型的设计如下: public ...
- Area 使用
[ASP.NET MVC 小牛之路]08 - Area 使用 ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Ar ...
- Github官方app分析——用户身份验证模块
这篇文章记述的是我对Giuhub官方app的用户身份验证模块的分析. Giuhub的官方app虽然是一个非常小众的程序,但是从程序的设计的角度看,这是一个非常优秀的项目.对于其用户身份验证模块,给我留 ...
- JQ与AJAX 省市区三级联动下拉框
用于初学者学习基本的联动下拉框,废话不多说,见代码 首先看控制器里的3个下拉框对应代码: public ActionResult GetProvinceList() { ProvinceReposit ...
- web.xml加载过程
web.xml加载过程:1 启动WEB项目的时候,容器(如:Tomcat)会读他的配置文件web.xml读两个节点 <listener></listener>和<con ...
- 博客已迁移到lizhug.com
新的博客地址 http://lizhug.com
- 抛掉kendoUI的MultiSelect,自己实现 DropDownList MultiSelect
我们首先来看下kendoUI官方的下拉框多选: 再来看看telerik RadControls的下拉框多选: 很明显从展现形式上来看,第二种是优于第一种的,至少我是这么认为的 :-) 那我们就对Dro ...
- 用django创建一个简单的sns
用django创建一个简单的sns 1.首先创建一个工程newsns django-admin.py startproject newsns 在工程目录下新建一个文件夹templates,在该文件夹下 ...
- hdu4474 Yet Another Multiple Problem
Yet Another Multiple Problem Description There are tons of problems about integer multiples. Despite ...
- zoj 1152 A Mathematical Curiosity
方法:枚举 做这道题,在第十行的位置WA了很多次,(n || m)不能写成(n + m),m可能是负数,一直没注意到,导致不停的WA....... #include <stdio.h> i ...