ChatGPT解决这个技术问题 Extra ChatGPT

对服务与工厂感到困惑

据我了解,在工厂内部时,我返回一个注入控制器的对象。在服务内部时,我正在使用 this 处理对象并且不返回任何内容。

我假设一个服务总是一个单例,并且一个新的工厂对象被注入到每个控制器中。然而,事实证明,工厂对象也是单例吗?

示例代码来演示:

var factories = angular.module('app.factories', []);
var app = angular.module('app',  ['ngResource', 'app.factories']);

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

当更改 ACtrl 中的 user.first 时,结果发现 BCtrl 中的 user.first 也发生了更改,例如 User 是单例?

我的假设是在带有工厂的控制器中注入了一个新实例?

在“module.service”和“module.factory”旁边,还有另外两种在 AngularJS 中创建服务的方法。有关详细信息,请查看博文:“How to create (singleton) AngularJS services in 4 different ways

A
Ander Biguri

所有角度服务都是单例:

文档(请参阅单例服务):https://docs.angularjs.org/guide/services

最后,重要的是要认识到所有 Angular 服务都是应用程序单例。这意味着每个注入器只有一个给定服务的实例。

基本上服务和工厂的区别如下:

app.service('myService', function() {

  // service is just a constructor function
  // that will be called with 'new'

  this.sayHello = function(name) {
     return "Hi " + name + "!";
  };
});

app.factory('myFactory', function() {

  // factory returns an object
  // you can run some code before

  return {
    sayHello : function(name) {
      return "Hi " + name + "!";
    }
  }
});

查看有关 $provide 的演示文稿:http://slides.wesalvaro.com/20121113/#/

这些幻灯片用于 AngularJs 聚会之一:http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html


另请参阅 stackoverflow.com/questions/15666048/…,其中讨论了服务、工厂和提供之间的区别。
官方文档间接[原文如此! not enought clear] 意味着即使您使用工厂定义服务,它也只创建一次。换句话说,它不会根据参考(注入点)再次创建 - 无论你怎么称呼它。两种方式都会导致每个注入器有一个单例实例。
你说“服务只是一个构造函数,将用'new'调用”,但我认为这是误导。我不认为它是在幕后用 new 调用的,我认为开发人员有责任在其上调用 new
@nfiniteloop,检查第 3574 行附近的源代码。工厂是提供者的 $get 方法,服务是使用在提供的函数上调用 $injector.instantiate 的方法生成工厂,然后调用 new。 (See Docs)
我的印象是,服务就像您通过引用它来使用的单例一样。而且工厂是一个单例,每次都返回一个新对象。也就是说,一项服务将为您提供一辆“汽车”,而您项目中的所有内容都将使用这辆汽车。每次您调用工厂时,工厂都会给您一辆新车。一个是返回单例的单例,一个是返回对象的单例。谁能解释一下?将所有内容称为单例并没有帮助,因为它可以引用多个事物。
R
Royi Namir

对我来说,当我意识到它们都以相同的方式工作时,我得到了启示:运行一次,存储它们获得的值,然后在通过依赖注入引用时咳出相同的存储值。

假设我们有:

app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);

三者的区别在于:

的存储值来自于运行 fn,换句话说:fn() b 的存储值来自于 newing fn,换句话说:new fn() c 的存储值来自于首先通过 newing fn 获取实例,然后运行 $get实例方法

这意味着,在 angular 内部有一个类似于缓存对象的东西,每次注入的值只分配一次,当它们第一次被注入时,并且在哪里:

cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()

这就是我们在服务中使用 this 并在提供程序中定义 this.$get 的原因。

希望这可以帮助。


最后,一个理智的解释。 Angular 很疯狂,而且非常糟糕,以至于它会受伤。
这应该是公认的答案,因为它实际上回答了为什么工厂、服务和提供者返回单例值的问题。其他答案解释了工厂、服务和提供者之间的区别,但从未涉及单例方面。
我喜欢这个……当我读到其他博主的千行句子时……我只能理解工厂。但我读了这个......我理解所有 3。
.service.factory 都是 .provide 的快捷方式。最后,所有服务都来自调用 .$get()
所以你必须在使用提供者时提供 $get 的实现?
C
Community

活生生的例子

“你好世界”的例子

factory / service / provider

var myApp = angular.module('myApp', []);
 
//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});
 
//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});
    
//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.
 
    this.name = 'Default';
 
    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };
 
    this.setName = function(name) {
        this.name = name;
    };
});
 
//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        
 
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​

J
JustGoscha

还有一种方法可以返回构造函数,这样您就可以在工厂中返回可更新的类,如下所示:

function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) { 
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 

因此,您可以在使用 MyObjectWithParam 的控制器中执行此操作:

var obj = new MyObjectWithParam("hello"),

请参阅此处的完整示例:
http://plnkr.co/edit/GKnhIN?p=preview

这里是 google 群组页面,讨论的地方:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ


我在使用您的示例时遇到了缩小问题。你知道我应该如何注释这个吗?
是的,Angular 有一个缩小的符号。它应该是这样的:App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]); 在此处阅读更多信息:docs.angularjs.org/tutorial/step_05
如果可以改用 .service,为什么要这样做?
我有同样的想法@flup。 @justgoscha,使用 .factory 而不是 .service 有什么好处(percieved?)?
我认为是因为服务是单例。我在这里构造的是基本上是一个类,它是新的。因此,您可以拥有像汽车服务工厂这样的东西,然后制作 new Car('BMW')new Car('Ford'),它们不会共享相同的变量和所有内容。
C
Community

以下是主要区别:

服务

语法:module.service( 'serviceName', function );

结果:将 serviceName 声明为可注入参数时,您将获得传递给 module.service函数实例

用法:对于共享实用函数很有用,只需将 () 附加到注入的函数引用即可调用。也可以使用 injectedArg.call( this ) 或类似方法运行。

工厂

语法:module.factory( 'factoryName', function );

结果:将 factoryName 声明为可注入参数时,您将获得通过调用传递给 module.factory 的函数引用返回的值。

用法:对于返回一个“类”函数可能很有用,然后可以新建该函数以创建实例。

还要检查 AngularJS documentation 和 stackoverflow confused about service vs factory 上的类似问题。

这是example using services and factory。阅读有关 AngularJS service vs factory 的更多信息。


这对我来说很有意义。 he 工厂返回创建新对象的蓝图。
A
Anand

除了第一个答案之外,我认为 .service() 适用于以更面向对象的风格(C#/Java)编写代码的人(使用 this 关键字并通过原型/构造函数实例化对象)。

Factory 适用于编写更自然的 javascript/函数式编码的代码的开发人员。

看一下 angular.js 中 .service 和 .factory 方法的源代码——在内部它们都调用了 provider 方法:

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn }); 
  }

  function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

b
bingles

很简单:

.service - 注册函数将作为构造函数调用(又名“newed”)

.factory - 注册函数将作为简单函数调用

两者都被调用一次,导致一个单例对象被注入到应用程序的其他组件中。


是的。让我们不要让事情变得比实际更复杂
L
Luis Perez

所有提供商的工作方式都相同。不同的方法 servicefactoryprovider 只是让您用更少的代码完成同样的事情。

PS 还有 valueconstant

provider 开始到 value 结束的每个特殊情况都有一个额外的限制。所以要在它们之间做出决定,你必须问自己,哪一个可以让你用更少的代码完成你想要的。

这是一张图片,向您展示了我的意思:

https://i.stack.imgur.com/CkdHl.png

您可以在我从以下位置获得这张图片的博客文章中获得细分和参考指南:

http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/


据说服务是单例的,但是如果每次注入时都创建新实例,它怎么会是单例的?
@AnkurMarwaha 不是每次都创建一个新实例,它只创建一次并由 AngularJS 缓存。无论您使用的是提供者、工厂、服务等,都是如此。您可以使用 console.log() 并注入多个控制器来确认这一点。
Luis,您的评论与它所说的已接受的答案相冲突——最后,重要的是要认识到所有 Angular 服务都是应用程序单例。这意味着每个注入器只有一个给定服务的实例。
@AnkurMarwaha 也许我误解了一些东西。您引用了“重要的是要意识到所有 Angular 服务都是应用程序单例”——它们是单例的事实意味着它们只创建一次。这就是我所说的“不是每次都创建一个新实例,它只创建一次并缓存......”。你能更详细地指出你看到冲突的地方吗?
啊,我看到了混乱。 “注射器”是一个有角度的物体。它负责进行“注射”。例如,当控制器第一次运行时,“注入器”会查看参数并注入每个参数。您的整个应用程序只有一个“注入器”。一旦注入器创建了一个特定的工厂或服务,它就会为它保留一个实例并重用它——因此是单例。所以每个应用程序只有一个注入器,每个注入器只有一个给定服务的实例。大多数 Angular 应用程序只有一个应用程序,因此只有一个注入器,因此任何服务、控制器等都有一个实例。
佚名

这里有更多关于服务与工厂的示例,它们可能有助于了解它们之间的区别。基本上,一个服务调用了“new ...”,它已经被实例化了。工厂不会自动实例化。

基本示例

返回具有单个方法的类对象

这是一个具有单一方法的服务:

angular.service('Hello', function () {
  this.sayHello = function () { /* ... */ };
});

这是一个返回带有方法的对象的工厂:

angular.factory('ClassFactory', function () {
  return {
    sayHello: function () { /* ... */ }
  };
});

返回一个值

返回数字列表的工厂:

angular.factory('NumberListFactory', function () {
  return [1, 2, 3, 4, 5];
});

console.log(NumberListFactory);

返回数字列表的服务:

angular.service('NumberLister', function () {
  this.numbers = [1, 2, 3, 4, 5];
});

console.log(NumberLister.numbers);

两种情况下的输出都是相同的,即数字列表。

高级示例

使用工厂的“类”变量

在这个例子中,我们定义了一个 CounterFactory,它增加或减少一个计数器,您可以获取当前计数或获取已创建的 CounterFactory 对象的数量:

angular.factory('CounterFactory', function () {
  var number_of_counter_factories = 0; // class variable

  return function () {
    var count = 0; // instance variable
    number_of_counter_factories += 1; // increment the class variable

    // this method accesses the class variable
    this.getNumberOfCounterFactories = function () {
      return number_of_counter_factories;
    };

    this.inc = function () {
      count += 1;
    };
    this.dec = function () {
      count -= 1;
    };
    this.getCount = function () {
      return count;
    };
  }

})

我们使用 CounterFactory 创建多个计数器。我们可以访问类变量来查看创建了多少计数器:

var people_counter;
var places_counter;

people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());

places_counter = new CounterFactory();
console.log('places', places_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());

这段代码的输出是:

people 0
people 1
counters 1
places 0
counters 2
counters 2

这是一个有用的例子,number_of_counter_factories 就像 CounterFactory 类的元属性,对吧?我知道这个例子可以在服务上复制(告诉我如果我错了),在这种情况下会有什么语义差异?
有用的例子!因此,这基本上意味着在工厂中,您可以拥有额外的抽象层,而这些抽象层不会在服务中获得。不管返回什么,只要使用“new”,就会返回它的一个新实例。任何未在返回块内声明的变量都是单例的。我做对了吗?
@Swanidhi 基本上是的,您可以在工厂中声明单例变量。这就是为什么我称它们为“类”变量。
S
Shivprasad Koirala

“工厂”和“服务”是 Angular 进行 DI(依赖注入)的不同方式。

因此,当我们使用“服务”定义 DI 时,如下面的代码所示。这将创建“Logger”对象的新 GLOBAL 实例并将其注入到函数中。

app.service("Logger", Logger); // Injects a global object

当您使用“工厂”定义 DI 时,它不会创建实例。它只是传递方法,之后消费者必须在内部调用工厂以获取对象实例。

app.factory("Customerfactory", CreateCustomer);

下面是一个简单的图像,它直观地显示了“服务”的 DI 流程与“工厂”的不同之处。

https://i.stack.imgur.com/M55Yi.png

当我们想根据场景创建不同类型的对象时,应该使用工厂。例如,根据场景,我们想要创建一个简单的“客户”对象,或“客户”与“地址”对象或“客户”与“电话”对象。 Here is a detailed explanation of this paragraph

当我们要注入实用程序或共享功能时,应该使用服务,例如 Utility , Logger , Error handler 等。


我在这个问题上看到的每个答案以及类似的其他答案都指定了机制和语法上的差异。这个答案给出了一个真正的理由,为什么你会选择一个而不是另一个。这是一个语义问题,查看名称、服务或工厂,传达它们的目的以及它们的使用方式。
P
Premraj

服务风格:(可能是最简单的一种)返回实际函数:对于共享实用函数很有用,这些实用函数只需将 () 附加到注入的函数引用即可调用。

AngularJS 中的服务是一个包含一组函数的单例 JavaScript 对象

var myModule = angular.module("myModule", []);

myModule.value  ("myValue"  , "12345");

function MyService(myValue) {
    this.doIt = function() {
        console.log("done: " + myValue;
    }
}

myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {

    myService.doIt();

});

工厂风格:(更复杂但更复杂)返回函数的返回值:在 java 中实例化一个像 new Object() 这样的对象。

工厂是一个创造价值的功能。当服务、控制器等需要从工厂注入的值时,工厂会按需创建该值。一旦创建,该值就会被所有需要注入的服务、控制器等重用。

var myModule = angular.module("myModule", []);

myModule.value("numberValue", 999);

myModule.factory("myFactory", function(numberValue) {
    return "a value: " + numberValue;
})  
myModule.controller("MyController", function($scope, myFactory) {

    console.log(myFactory);

});

提供者风格:(完整的、可配置的版本)返回函数的 $get 函数的输出:可配置。

AngularJS 中的提供者是您可以创建的最灵活的工厂形式。您可以像使用服务或工厂一样向模块注册提供程序,但您使用 provider() 函数代替。

var myModule = angular.module("myModule", []);

myModule.provider("mySecondService", function() {
    var provider = {};
    var config   = { configParam : "default" };

    provider.doConfig = function(configParam) {
        config.configParam = configParam;
    }

    provider.$get = function() {
        var service = {};

        service.doService = function() {
            console.log("mySecondService: " + config.configParam);
        }

        return service;
    }

    return provider;
});

myModule.config( function( mySecondServiceProvider ) {
    mySecondServiceProvider.doConfig("new config param");
});

myModule.controller("MyController", function($scope, mySecondService) {

    $scope.whenButtonClicked = function() {
        mySecondService.doIt();
    }

});

src jenkov

JS Bin {{serviceOutput}}

{{factoryOutput}}

{{providerOutput}}

jsbin

JS Bin

{{hellos}}

jsfiddle


y
yoel halb

基本区别在于,提供者允许将原始(非对象)、数组或回调函数值设置到工厂声明的变量中,因此如果返回一个对象,则必须显式声明并返回它。

另一方面,服务只能用于将服务声明的变量设置为对象,因此我们可以避免对象的显式创建和返回,而另一方面它允许使用 this 关键字。

或者简而言之,“提供者是一种更通用的形式,而服务仅限于对象”。


H
Hisham

这就是我在设计模式方面理解它们之间的区别的方式:

服务:返回一个类型,它将被更新以创建该类型的对象。如果使用 Java 类比,Service 返回一个 Java 类定义。

Factory:返回一个可以立即使用的具体对象。在 Java 类比中,工厂返回一个 Java 对象。

经常让人们(包括我自己)感到困惑的部分是,当您在代码中注入服务或工厂时,它们可以以相同的方式使用,在这两种情况下,您在代码中得到的是一个可以立即调用的具体对象。这意味着在服务的情况下,角度代表您在服务声明中调用“新”。我认为这是一个复杂的概念。


S
Syed Ekram Uddin

这将是理解 Service Vs Factory Vs Provider 的最佳和简短答案

来源https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J

以下是 bendemo 说的http://jsbin.com/ohamub/1/edit?html,output

“代码中有一些注释说明了主要区别,但我会在这里对它们进行一些扩展。作为说明,我只是对此有所了解,所以如果我说任何错误的地方,请告诉我。

服务

语法:module.service('serviceName', function);

结果:将 serviceName 声明为可注入参数时,将为您提供传递给 module.service 的实际函数引用。

用法:对于共享实用函数很有用,只需将 () 附加到注入的函数引用即可调用。也可以使用 injectArg.call( this ) 或类似方法运行。

工厂

语法:module.factory('factoryName', function);

结果:当将 factoryName 声明为可注入参数时,您将获得通过调用传递给 module.factory 的函数引用返回的值。

用法:对于返回一个“类”函数可能很有用,然后可以新建该函数以创建实例。

提供者

语法:module.provider('providerName', function);

结果:当将 providerName 声明为可注入参数时,您将获得通过调用传递给 module.provider 的函数引用的 $get 方法返回的值。

用法:对于返回一个“类”函数可能很有用,然后可以新建该函数以创建实例,但这需要在注入之前进行某种配置。也许对跨项目可重用的类有用?这个还是有点朦胧。”本


S
Safeer Hussain

我有一段时间感到困惑,我正在尽力在这里提供一个简单的解释。希望这会有所帮助!

angular .factoryangular .service 都用于初始化服务并以相同的方式工作。

唯一的区别是,您希望如何初始化您的服务。

两者都是单身人士

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

工厂

app.factory(, )

如果您想从具有返回值的函数初始化您的服务,则必须使用此 factory 方法。

例如

function myService() {
  //return what you want
  var service = {
    myfunc: function (param) { /* do stuff */ }
  }
  return service;
}

app.factory('myService', myService);

注入此服务时(例如,注入您的控制器):

Angular 将调用你给定的函数(作为 myService())来返回对象

Singleton - 只调用一次,存储和传递同一个对象。

服务

app.service(<服务名称>, <构造函数>)

如果您想从构造函数(使用 this 关键字)初始化您的服务,则必须使用此 service 方法。

例如

function myService() {
  this.myfunc: function (param) { /* do stuff */ }
}

app.service('myService', myService);

注入此服务时(例如,注入您的控制器):

Angular 将更新您的给定函数(作为 new myService())以返回对象

Singleton - 只调用一次,存储和传递同一个对象。

工厂

<构造函数>

服务

<有返回值的函数>

示例 - 演示

Angular 服务与工厂

Angular 服务与工厂(带路由)


J
James Drinkard

多亏了 Pascal Precht 的一篇博文,这帮助我理解了其中的区别。

服务是模块上的一种方法,它采用名称和定义服务的函数。您可以在其他组件(如控制器、指令和过滤器)中注入和使用该特定服务。工厂是模块上的一种方法,它还带有一个名称和一个函数,用于定义工厂。我们也可以像处理服务一样注入和使用它。

使用 new 创建的对象使用其构造函数的原型属性的值作为其原型,因此我找到了调用 Object.create() 的 Angular 代码,我相信它是实例化时的服务构造函数。然而,工厂函数实际上只是一个被调用的函数,这就是为什么我们必须为工厂返回一个对象字面量。

这是我为工厂找到的 Angular 1.5 代码:

var needsRecurse = false;
    var destination = copyType(source);

    if (destination === undefined) {
      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
      needsRecurse = true;
    }

factory() 函数的 Angular 源代码片段:

 function factory(name, factoryFn, enforce) {
    return provider(name, {
      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
    });
  }

它接受名称和传递的工厂函数,并返回一个具有相同名称的提供者,它有一个 $get 方法,这是我们的工厂函数。每当您向注入器询问特定依赖项时,它基本上都会通过调用 $get() 方法向相应的提供者询问该服务的实例。这就是创建提供程序时需要 $get() 的原因。

这是用于服务的 Angular 1.5 代码。

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

原来我们调用service()的时候,其实调用的是factory()!但是,它不只是将我们的服务构造函数按原样传递给工厂。它还传递了一个函数,该函数要求注入器通过给定的构造函数实例化一个对象。

换句话说,如果我们在某处注入 MyService,代码中会发生什么:

MyServiceProvider.$get(); // return the instance of the service

再次重申它,服务调用工厂,这是相应提供程序上的 $get() 方法。此外,$injector.instantiate() 是最终使用构造函数调用 Object.create() 的方法。这就是我们在服务中使用“this”的原因。

对于 ES5,我们使用哪个无关紧要:service() 或 factory(),它始终是一个被调用的工厂,它为我们的服务创建一个提供者。

你也可以对服务做同样的事情。服务是一个构造函数,但是,它不会阻止我们返回对象字面量。所以我们可以把我们的服务代码写成它基本上和我们的工厂做同样的事情,或者换句话说,你可以把服务写成工厂来返回一个对象。

为什么大多数人建议使用工厂而不是服务?这是我从 Pawel Kozlowski 的书:Mastering Web Application Development with AngularJS 中看到的最佳答案。

工厂方法是将对象放入 AngularJS 依赖注入系统的最常用方法。它非常灵活,可以包含复杂的创建逻辑。由于工厂是常规函数,我们还可以利用新的词法作用域来模拟“私有”变量。这非常有用,因为我们可以隐藏给定服务的实现细节。”


O
Oskar

使用工厂,您实际上在工厂内部创建了一个对象并将其返回。

使用该服务,您只需一个使用 this 关键字定义函数的标准函数。

使用提供程序,您可以定义一个 $get ,它可用于获取返回数据的对象。


P
Pritam Banerjee

在 AngularJS 中有三种处理业务逻辑的方法:(受 Yaakov 的 Coursera AngularJS 课程启发)它们是:

服务工厂供应商

这里我们只讨论Service vs Factory

服务:

句法:

应用程序.js

 var app = angular.module('ServiceExample',[]);
 var serviceExampleController =
              app.controller('ServiceExampleController', ServiceExampleController);
 var serviceExample = app.service('NameOfTheService', NameOfTheService);

 ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files

function ServiceExampleController(NameOfTheService){
     serviceExampleController = this;
     serviceExampleController.data = NameOfTheService.getSomeData();
 }

function NameOfTheService(){
     nameOfTheService = this;
     nameOfTheService.data = "Some Data";
     nameOfTheService.getSomeData = function(){
           return nameOfTheService.data;
     }     
}

索引.html

<div ng-controller = "ServiceExampleController as serviceExample">
   {{serviceExample.data}}
</div>

服务的主要特点:

惰性实例化:如果服务没有被注入,它将永远不会被实例化。因此,要使用它,您必须将其注入到模块中。单例:如果它被注入到多个模块中,那么所有模块都只能访问一个特定的实例。这就是为什么在不同的控制器之间共享数据非常方便。

工厂

现在让我们谈谈AngularJS中的工厂

首先让我们看一下语法:

应用程序.js:

var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);

//first implementation where it returns a function
function NameOfTheFactoryOne(){
   var factory = function(){
      return new SomeService();
    }
   return factory;
}

//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
   var factory = {
      getSomeService : function(){
          return new SomeService();
       }
    };
   return factory;
}

现在在控制器中使用上述两个:

 var factoryOne = NameOfTheFactoryOne() //since it returns a function
 factoryOne.someMethod();

 var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
 factoryTwo.someMethod();

工厂特点:

这种类型的服务遵循工厂设计模式。工厂可以被认为是创建新对象或方法的中心位置。这不仅会产生单例,还会产生可定制的服务。 .service() 方法是一个工厂,它总是产生相同类型的服务,即单例。没有简单的方法来配置它的行为。该 .service() 方法通常用作不需要任何配置的快捷方式。


I
Ishpreet

有关简短的说明,请参阅 https://stackoverflow.com/a/26924234/5811973

有关详细说明,请参阅 https://stackoverflow.com/a/15666049/5811973

https://i.stack.imgur.com/24jgv.png


S
Sourabh Ranka

您可以通过这个类比来理解差异 - 考虑将返回一些值的普通函数和将使用 new 关键字实例化的构造函数之间的区别。因此创建工厂类似于创建将返回一些值的普通函数(原始或一个对象),而创建服务就像创建构造函数(OO 类),我们可以使用 new 关键字创建实例。唯一需要注意的是,当我们使用 Service 方法创建服务时,它会使用 AngularJS 支持的依赖注入机制自动创建它的实例


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅