zoukankan      html  css  js  c++  java
  • 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中相同的方法,而不是通过曾经那种复制的方法来解决。
    分层编写代码的最终目的无非就是

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

      最后的最后

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



    文/AkiraPan(简书作者)
    原文链接:http://www.jianshu.com/p/1e1aaf0fd30a
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 相关阅读:
    重写方法,重载方法,虚方法和抽象方法的使用
    基类和派生类
    C#修饰符讲解大全
    通过HTTP请求WEBAPI的方式
    计算机各种协议讲解
    时间戳
    SQL Server知识详解
    基本概念和术语
    22.C++- 继承与组合,protected访问级别
    22.QT-QXmlStreamReader解析,QXmlStreamWriter写入
  • 原文地址:https://www.cnblogs.com/Uncle-Maize/p/5916663.html
Copyright © 2011-2022 走看看