15

我刚刚开始使用 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);
  };
}

在这种情况下,您什么时候选择使用服务?

4

5 回答 5

31

在我看来,主要原因是:

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

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

  • 干燥(不要重复自己)。
    IE:您在不同的控制器中有一系列您需要的功能,如果没有服务,您将不得不在每个控制器中重复您的代码,使用服务您可以为这些功能创建一个 API 并将其注入每个控制器/指令/您需要的服务。

这是一个例子:

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.

}]);
于 2013-05-23T09:46:12.397 回答
8

根据我的经验,服务在以下情况下会派上用场:

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

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

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

于 2013-05-23T09:11:34.323 回答
2

当您想在导航期间将变量保留在内存中(为什么不,例如用户会话)时(调用具有不同控制器的不同部分)。你必须记住:

  • 每次调用控制器时都会重新初始化控制器。

  • 服务只构建一次并且始终可用。因此,您可以保留所需的任何信息。

于 2013-05-23T09:29:01.433 回答
1

除了上面列出的好处之外,它还可以帮助您将应用程序结构划分为独立的组件,这也使其更易于理解和测试。

想象一下,必须在多个地方测试类似的功能,而不是在一个中心位置定义/调试它并在其他地方使用(多次)。

于 2014-03-26T08:14:11.037 回答
0

还要提醒 Angular 服务是单例对象(它非常重要,因此我们可以通过项目轻松共享它),它们在应用程序的生命周期中只被实例化一次。它们包含在应用程序的整个生命周期中维护数据的方法,即数据不会被刷新并且始终可用。服务的主要目标是与 Angular 应用程序的不同组件组织和共享业务逻辑、模型或数据和功能。

于 2019-05-05T12:42:45.023 回答