初学者的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中相同的方法,而不是通过曾经那种复制的方法来解决。
分层编写代码的最终目的无非就是

  1. 增加代码的复用性;
  2. 代码责任简单,不会又做保姆又做司机,可读性强容易理解;
  3. 编写测试代码的时候容易编写;
  4. 减少对一些框架和环境插件的依赖;
  5. 修改逻辑时最小幅度的修改代码
  6. 数据层发生变更修改Service,UI层有变化则修改Controller。不用担心改controller把service也一起带到沟里的情况发生。

    最后的最后

    AngularJS在许多框架的设计方面与Java的Spring非常类似,如你有一定的Java基础应该很能理解为赢编写出分层的代码。

文/AkiraPan(简书作者)
原文链接:http://www.jianshu.com/p/1e1aaf0fd30a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

AngularJS中如何对Controller与Service进行分层设计与编码的更多相关文章

  1. angularjs中provider,factory,service的区别和用法

    angularjs中provider,factory,service的区别和用法 都能提供service,但是又有差别 service 第一次被注入时实例化,只实例化一次,整个应用的生命周期中是个单例 ...

  2. AngularJS中的Provider们:Service和Factory等的区别

    引言 看了很多文章可能还是不太说得出AngularJS中的几个创建供应商(provider)的方法(factory(),service(),provider())到底有啥区别,啥时候该用啥,之前一直傻 ...

  3. angularJS中directive与controller之间的通信

    当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...

  4. [译]AngularJS中几种Providers(Factory, Service, Provider)的区别

    原文: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/ 什么是Provider? Angula ...

  5. AngularJS中Model和Controller传值问题

    最近由于工作原因,开始写点前端的东西.前两天刚开始了解AngularJS这门技术,当然,新手免不了会爬坑! 今天分享一篇关于--> 模型传参给Controller的实例: 需求: 具体是  首先 ...

  6. 八、angularjs 中 filter在controller中的使用--避免多次遍历

    filter在html页面的使用司空见惯,比如: filter在controller中使用可以避免多次使用angular.foreach,来进行遍历.例如: 如果使用filter,则会让代码简洁而且明 ...

  7. AngularJS 中 Provider 的用法及区别

    在一个分层良好的 Angular 应用中,Controller 这一层应该很薄.也就是说,应用里大部分的业务逻辑和持久化数据都应该放在 Service 里. 为此,理解 AngularJS 中的几个 ...

  8. 怎么理解angularjs中的服务?

    AngularJS中的服务其实就是提供一种方式抽取共用类库 比如说一些工具类方法,我们传统的做法就是自己写个 utility 类,把相关的工具方法填充到utility里面去,最后把utility类放到 ...

  9. AngularJS中使用Directive、Controller、Service

    AngularJS是一款非常强大的前端MVC框架.同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉. (1)Directive 指令 (2)Controller 控制器 (3)Service ...

随机推荐

  1. MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 二

    本次改动的主要内容是实现MongoDB.Repository对MongoDBRef的支持. MongoDB对一对一,一对多,多对多关系的维护,官方推荐文档嵌入方式,反映到模型的设计如下: public ...

  2. Area 使用

    [ASP.NET MVC 小牛之路]08 - Area 使用 ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Ar ...

  3. Github官方app分析——用户身份验证模块

    这篇文章记述的是我对Giuhub官方app的用户身份验证模块的分析. Giuhub的官方app虽然是一个非常小众的程序,但是从程序的设计的角度看,这是一个非常优秀的项目.对于其用户身份验证模块,给我留 ...

  4. JQ与AJAX 省市区三级联动下拉框

    用于初学者学习基本的联动下拉框,废话不多说,见代码 首先看控制器里的3个下拉框对应代码: public ActionResult GetProvinceList() { ProvinceReposit ...

  5. web.xml加载过程

    web.xml加载过程:1 启动WEB项目的时候,容器(如:Tomcat)会读他的配置文件web.xml读两个节点  <listener></listener>和<con ...

  6. 博客已迁移到lizhug.com

    新的博客地址 http://lizhug.com

  7. 抛掉kendoUI的MultiSelect,自己实现 DropDownList MultiSelect

    我们首先来看下kendoUI官方的下拉框多选: 再来看看telerik RadControls的下拉框多选: 很明显从展现形式上来看,第二种是优于第一种的,至少我是这么认为的 :-) 那我们就对Dro ...

  8. 用django创建一个简单的sns

    用django创建一个简单的sns 1.首先创建一个工程newsns django-admin.py startproject newsns 在工程目录下新建一个文件夹templates,在该文件夹下 ...

  9. hdu4474 Yet Another Multiple Problem

    Yet Another Multiple Problem Description There are tons of problems about integer multiples. Despite ...

  10. zoj 1152 A Mathematical Curiosity

    方法:枚举 做这道题,在第十行的位置WA了很多次,(n || m)不能写成(n + m),m可能是负数,一直没注意到,导致不停的WA....... #include <stdio.h> i ...