为什么在Angular中使用服务?

Ale*_*x D 14 service angularjs

我刚刚开始使用Angular.阅读Google文档中的服务示例,我只是想知道为什么您会选择使用服务而不是将变量和函数保留在控制器中?

angular.
 module('MyServiceModuleDI', []).
 factory('notify', function($window) {
    var msgs = [];
    return function(msg) {
      msgs.push(msg);
      if (msgs.length == 3) {
        $window.alert(msgs.join("\n"));
        msgs = [];
      }
    };
  });

function myController($scope, notify) {
  $scope.callNotify = function(msg) {
    notify(msg);
  };
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您何时会选择使用服务?

Ber*_*and 30

在我看来,主要原因是:

  • 在控制器之间保持并共享数据.
    IE:您创建一个从数据库中获取数据的服务,如果您将其存储在控制器中,一旦您更改为另一个Controller,数据将被丢弃(除非您将其存储在$ rootScope中,但这不是最好的方法)它),但是如果你将它保存在服务中(服务是单例),当你更改控制器时数据将保持不变.

  • 通过创建将由控制器/指令/服务使用的API来抽象数据访问逻辑.
    将业务逻辑保留在服务器内的控制器和数据逻辑中.

  • 干(不要重复自己).
    IE:您需要在不同的控制器中使用一系列功能,而无需在每个控制器中重复代码的服务,使用服务可以为此功能创建单个API并将其注入每个Controller/Directive /您需要的服务.

这是一个例子:

var myApp = angular.module('myApp',[]);


//Here is the service Users with its functions and attributes
//You can inject it in any controller, service is a singleton and its data persist between controllers
myApp.factory('Users', function () {

    //data logic
    //fetch data from db and populate...
    var name = "John";
    var surname = "Doe" 

    function getName() { return name; }
    function getFullName() { return name + ' ' + surname; }
    function setName(newName) { name = newName; }

    //API
    return {
        getName: getName,
        getFullName: getFullName,
        setName: setName
    }
});

//An Util service with methods I will use in different controllers   
myApp.factory('Util', function () {

    //a bunch of useful functions I will need everywhere
    function daysInMonth (month,year) {
        return new Date(year, month+1,0).getDate();
    }

    return {
        daysInMonth: daysInMonth    
    };
});   

//Here I am injecting the User and Util services in the controllers   
myApp.controller('MyCtrl1', ['$scope', 'Users', 'Util', function ($scope, Users, Util) {

    $scope.user = Users.getFullName(); //"John Doe";
    Users.setName('Bittle');

    //Using Util service
    $scope.days = Util.daysInMonth(05,2013);
}]);

myApp.controller('MyCtrl2', ['$scope', 'Users', 'Util', function ($scope, Users, Util) {

    $scope.user = Users.getFullName(); //"Bittle Doe"; //The change that took place in MyCtrl1 hhas persisted.

}]);
Run Code Online (Sandbox Code Playgroud)

  • 工厂正在使用[模块模式](http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html),在服务的返回对象中放入要公开的方法,[参见示例](http://jsbin.com/picat/4/edit). (2认同)

cal*_*tie 8

根据我的经验,服务在以下场景中派上用场:

  1. 当您希望在两个或更多控制器之间共享信息时,
    可以使用$rootScope控制器之间进行通信,但正如文档中常见的陷阱部分所示,应尽可能避免它,因为它是全局范围.使用服务,我们可以定义可以轻松用于在控制器之间交换数据的setter和getter方法.

  2. 当一个功能被多次使用时
    让我们说你有一个功能可以在你拥有的所有模板中重复 - 比如说你需要重复将货币从USD转换成欧元并向用户显示金额.在这里你可以假设"金额"是购买机票,在线购买一些书籍 - 任何与钱有关的东西.
    此功能将用于所有模板,以向客户显示始终为欧元的金额 - 但在您的数据库/模型中,金额以欧元存储.
    因此,您可以创建一个将金额从美元转换为欧元的服务.任何控制器都可以调用它并使用它.您的功能现在位于一个位置,而不是控制器.因此,将来如果您决定进行更改并以磅为单位显示金额,则需要仅在一个位置进行更改,并且它将反映在使用它的所有控制器上.

还有一些其他用例,但目前我只能想到这些用例.我自己发现使用服务的最常见的用例是第1点 - 在控制器之间传递数据.