【问题标题】:Should I use only a service for all my controllers?我应该只为我的所有控制器使用一项服务吗?
【发布时间】:2018-07-13 13:35:48
【问题描述】:

我在 Angular 中创建了一个服务,就像:

function dbService($http) {
    var instance = '';

    var service = {
        add: add,
        instance: instance
    };
    
    return service;

    function add(object) {
        return $http.post('/api/' + this.instance, object);
    }
}

我只在每次调用服务时更改实例属性,因为我注意到每个服务都具有相同的配置,但只更改控制器名称。有些人喜欢:

$scope.send() = function() {
    dbService.instance="Cars";
   
    dbService.add($scope.car).then(
    function(data) {
        console.log(data);
    },
    function(error) {
        console.log(error);
    }
};

什么样的问题可以给我这种方法?我应该为每个 Controller 创建一个服务(例如“CarsService”等),还是应该继续这种方法?

提前致谢!

【问题讨论】:

  • 这里使用dbService单例对象是一个错误。应该有多个对象实例。它们应该是不同的服务(这对于没有逻辑但 add 方法的当前服务没有意义,但在它负责处理响应时才有意义,因为它应该在正确的 MVC/MVVM 中)。或者 dbService 可以变成 dbServiceFactory 并在控制器中使用时返回一个类或对象实例,例如var carDbService = dbServiceFactory('car')(这取决于您需要什么,因为 carDbService 在不同的控制器中不会是单例)。

标签: angularjs angularjs-service


【解决方案1】:

一项服务足以满足所有控制器的需求。我使用以下服务没有任何问题。

(function() {
  'use strict';
var HttpServiceApp = angular.module('app');


var Http = function($http) {

  var HttpObject = {};

  HttpObject.get = function(route) {
    return $http.get(route)
      .then(function(response) {
        return response.data;
      });
  };

  HttpObject.post = function(route, data) {
    // console.log(data);
    return $http.post(route, data).then(function(responce) {
      // console.log("response :: " + JSON.stringify(responce));
      return responce.data;
    });
  };



  HttpObject.getParams = function(route, params) {
    var requestData = {
      method: "GET",
      url: route,
      params: params
    };

    return HttpObject.request(requestData);
  };


  HttpObject.request = function(request_data) {
    return $http(request_data).then(function(response) {
      return response.data;
    });
  };

  return HttpObject;

};

HttpServiceApp.factory('Http', ['$http', Http]);
})();

控制器

$scope.send() = function(){

                   Http.post("api/Cars",$scope.car).then(
                   function(data){
                         console.log(data);
                   },
                  function(error){
                         console.log(error);
                   }
                 };

【讨论】:

    【解决方案2】:

    @estus 是对的。虽然我不知道具体的用例,但怀疑使用单个服务并不是最好的解决方案。

    我建议您查看Restangular。使用这个库,您可以为封装 API 逻辑的每个资源(端点)定义一个服务。 使用restangular应用于您的示例:

    • 定义资源:汽车(您可以使用自定义方法进行扩展)
    • 将其注入需要使用它的控制器上。

    通过这种方法,您的代码与SRP 匹配得更好,而且可读性和易于理解。

    cars.resource.js

    angular.module('resources')
        .factory('Cars', CarsFactory);
    
    function CarsFactory(Restangular, API_ENDPOINT) {
        return Restangular.withConfig(function(RestangularConfigurer) {
            RestangularConfigurer.setBaseUrl(API_ENDPOINT);
    
            RestangularConfigurer.extendModel('cars', function(model) {
                 //Extend the resource with custom funcions
                 model.getParts = function() {
                    return model.getList('parts');
                };
                return model;
            });
        }).service('cars');
      }
    })();
    

    controller.js

    angular.module('myapp',[resources])
        .controller('MyCtrl',['$scope','Cars', MyCtrlFunction]);
    
    function MyCtrlFunction($scope, Cars]) {
      $scope.send() = function(){
         Cars.save($scope.car).then (...)
    
      }
    };
    

    【讨论】:

      【解决方案3】:

      服务是单例的;您没有单独的实例,不需要instance 属性。
      您实际上不需要在此处存储任何状态,因此只需使用纯函数即可:

      function dbService($http) {
      
          var service = {
              add: add,
          };
      
          return service;
      
          function add(objectType, object) {
              return $http.post('/api/' + objectType, object);
          }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-29
        • 2016-12-27
        相关资源
        最近更新 更多