初学者的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. TD中{text-overflow:ellipsis;} 用法

    Styles: table{ table-layout:fixed; } table td{ text-overflow:ellipsis;overflow:hidden;white-space: n ...

  2. Linux环境进程间通信(四):信号灯

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  3. 解决js中传值,Action获取是乱码问题

    1.先在js中进行编码 var str = $("mytext").val(); //转码,两次 str = encodeURI(str); str = encodeURI(str ...

  4. TPL相关

    C#中的Timer System.Windows.Forms.TimerSystem.Threading.Timer System.Timers.Timer 1.System.Windows.Form ...

  5. 自定义生命周期的设计(iOS篇)

    自定义生命周期的设计(iOS篇) 首先要确定一点,我们的App,要基于XIB文件进行编程,而不是在每个相应的ViewController里面去手动创建页面的每个控件.这样做的好处是,将页面布局与业务逻 ...

  6. jQuery Easing 动画效果扩展

    jQuery API提供了简单的动画效果如淡入淡出以及自定义动画效果,而今天我给大家分享的是一款jQuery动画效果扩展增强插件jquery.easing.js,使用该插件可以实现直线匀速运功.变加速 ...

  7. 添加可运行的js代码

    如何在博客园的文章/随笔中添加可运行的js代码 在博客园浏览大牛们写的文章时,经常会看到在文章中混有一些可运行示例,例如司徒正美的博客中: 带有可运行示例 可以点击“运行代码” 经过一番小小的探索,掌 ...

  8. 博客已迁移到lizhug.com

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

  9. Microsoft 电信项目组 Net代码生成器1.1

    Microsoft 电信项目组 Net代码生成器1.1 微软电信项目组代码生成器 为什么要使用这个代码生成器: 1.这个代码生成器采用 微软 企业库5.0 版本,目前CAPO所在的项目组都在使用这个 ...

  10. fastboot,bootloader,recovery

    Fastboot模式,在这个模式下,我们可以为手机进行解锁.可以在该模式下连接电脑进行软件或者指令解锁(s-off),这个模式也称“下载模式” Fastboot fastboot是一种比recover ...