我应该使用工厂或服务来获取AngularJS中的数据吗?

时间:2014-04-15 03:15:20

标签: javascript angularjs design-patterns

我正在学习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方式。

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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();
});

注意我必须手动调用新的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 Factory的用法完全相同。它是一个单例对象,您可以使用它来共享控制器之间的数据或功能。

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

引擎盖下,服务和工厂都使用提供商。通过服务,为您提供工厂功能。有了工厂,您可以随心所欲地完成任务。