【问题标题】:Should I use factory or service for fetching data in AngularJS? [duplicate]我应该使用工厂还是服务在 AngularJS 中获取数据? [复制]
【发布时间】:2014-05-29 05:39:57
【问题描述】:

我正在学习 AngluarJS,我有一个非常简单的项目设置。

我有一个名为 ApiService.js 的文件,用于从某处的 RESTful 服务器中提取数据。目前它看起来像这样:

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

module.service('ApiService', function() {
    this.getDataList = function() {
       ...
       ...
    }
});

然后我有一个像这样使用它的控制器:

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

module.controller('dataController', function($scope, ApiService) {
    $scope.dataList = ApiService.getDataList();
});

我不确定是否应该在我的 services.js 中使用 module.service 或 module.factory(这也让我感到困惑,约定是当工厂可以在那里时调用文件 services.js)。我知道工厂是什么,我知道常规软件设计模式中的服务是什么,但我不知道我应该怎么做才能以 Angular 的方式做到这一点。

什么是正确的,服务还是工厂?

【问题讨论】:

  • 查看这篇文章,了解 AngularJS 中的工厂、服务和提供者的详细说明:stackoverflow.com/questions/15666048/…
  • 差异是如此微妙;我不认为这很重要。当我开始时,我使用工厂,但已经转向服务。
  • 我已经阅读了这个问题,但我仍然不确定。我觉得我应该使用服务,因为 dataApi 在我的应用程序中的任何地方都应该是相同的。工厂每次都会创建一个新实例。
  • @CameronBall A Factory 不会每次都创建一个新实例。我在正式答案中对此进行了详细说明;因为我认为您可能正在经历与我最初一样的“困惑”。

标签: javascript angularjs design-patterns


【解决方案1】:

我想我会在一个真实的答案中详细说明一下。我相信服务和工厂之间的差异是如此微妙,这并不重要。

但是,您说您知道设计模式中的工厂和服务是什么。我想我会详细说明这一点,因为我认为应用于 AngularJS 的工厂和服务有点误导。

首先,Factory design pattern 基本上是一个创建其他对象的对象。但是,当您在 AngularJS 中创建工厂时;您不使用该工厂来创建其他对象。从 Angular 工厂返回的对象是一个单例,当您访问该工厂时,只会返回一个对象。因此,Angular 工厂与我在传递中使用的“工厂”具有不同的含义。事实上,当你创建一个 Angular 工厂时,你负责在工厂函数中创建对象。创建对象后,始终返回相同的对象。因此,Angular 工厂甚至一次都不会创建新对象。它不像我从其他语言中理解的工厂。

Service design pattern 实际上只是一种组织不同功能的奇特方式,以便将其与它们分开。当我在学校的时候,我们只是把它叫做“封装”,我不认为它是一种设计模式。 AngularJS 服务和 AngularJS 工厂都可以帮你做到这一点。

Angular Service 也是一个单例,但第一次引用该服务时,它将在相关对象上调用“new”。这意味着该服务创建了一个新对象——因此 AngularJS 服务更像是一个工厂而不是 AngularJS 工厂。 Angular 服务仍然是单例的,因此一旦创建对象,将始终返回相同的对象。

出于所有实际目的,我使用服务。它们似乎更容易设置。但差异似乎非常微妙。


好的,让我们详细说明一下工厂和服务的工作原理。

说,你有一个像这样创建的对象:

MyObject - function MyObject(){
 foo : "bar";
}

这个对象存在于 AngularJS 之外,可以在任何 JavaScript 中使用。如果您想将其与工厂一起使用;你会做这样的事情:

MyApp.factory('MyObjectFactory', function(){
    return new MyObject();
});

请注意,我必须手动调用 new MyObject() 函数来在工厂函数中创建一个新对象。我也可以返回一个现有对象,如下所示:

MyApp.factory('MyObjectFactory', function(){
    return MyObject;
});

现在,您想将它传递给这样的控制器:

function MyController($scope, MyObjectFactory) {}

Angular 在控制器中找到参数并查找 MyObjectFactory。如果它尚未实例化,则调用工厂函数并返回结果。结果被缓存了,所以每次 Angular 需要引用 MyObjectFactory 时,它都会返回第一次创建的同一个对象。 Singleton 中返回的对象,这就是您可以在不同控制器之间共享同一对象的方式。

这里的重点是工厂函数执行一次;首次进入工厂。它不用于管理同一类型的多个对象的创建。

同一个对象的服务可以这样创建:

MyApp.service('MyObjectService', MyObject);

并传入同一个控制器,像这样:

function MyController($scope, MyObjectFactory, MyObjectService) {}

当 Angular 第一次需要引用 MyObjectService 时,它​​会执行“new MyObject()”并返回那个对象。该对象被缓存,每次需要 MyObjectService 时,都会返回相同的对象。

在这个创建过程之后,它的用法与 AngularJS 工厂相同。它是一个单例对象,您可以使用它在控制器之间共享数据或功能。

因此,简而言之,当使用服务时,会自动创建对象的新实例。使用工厂时,工厂函数返回的任何对象都会被返回。

在后台,Service 和 Factory 都使用提供程序。通过服务为您提供工厂功能。有了工厂,你可以随心所欲地制作函数。

【讨论】:

  • Angular factory 是一个简单的javascript函数,负责创建、对象和返回。此函数在应用程序的生命周期内只被调用一次,并且结果在任何地方都可以重用。我不确定您对工厂的定义是否正确。 In fact, when you create an Angular factory, you pass the object into it and that object is always returned. So an Angular Factory does not even create a new object even once. It is nothing like a factory as I understood them from other languages.
  • @Chandermani 与 AngularJS 工厂;未创建新对象。 'new' 函数是使用 AngularJS 服务调用的,而不是使用工厂调用的。对于工厂,您可以调用“新”函数,因此工厂根本不会创建新对象。有关详细信息,请参阅此详细说明:stackoverflow.com/questions/15666048/…
  • 我说的是你使用return someObj从工厂函数返回的对象,是的,工厂函数只是一个javascript函数。
  • @Chandermani 我更新了我的问题以详细说明更多样本。也许我在互相交流;但你还没有说任何让我认为我不正确的话。最初的发布者犯了我最初做的同样的错误——假设工厂每次都会创建一个新对象,因为这是我在其他开发经验中通常使用的工厂。 AngularJS 工厂不是这样运作的。
  • @Chandermani 和我重新编写了您指出的文本;因为你是对的,这是误导。一个函数被传递到一个 AngularJS 工厂;不是通用对象实例。
猜你喜欢
  • 2015-10-31
  • 2014-12-26
  • 1970-01-01
  • 2023-03-08
  • 2015-07-01
  • 2013-10-15
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多