dependency-injection service使用 factory - AngularJS:服务与提供商vs工厂



15 Answers

JS小提琴演示

factory / service / provider “Hello world”示例:

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() {

    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()];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
</body>

angularjs dependency-injection angularjs-service angularjs-factory angularjs-provider

AngularJS中的ServiceProviderFactory之间有什么区别?




所有服务都是单身人士 ; 他们每个应用程序实例化一次。 它们可以是任何类型 ,无论是原始类型,对象文字,函数,还是自定义类型的实例。

valuefactoryserviceconstantprovider方法都是提供者。 他们教Injector如何实例化服务。

最详细,但也是最全面的是提供者食谱。 剩下的四种食谱类型 - 价值,工厂,服务和常数 - 只是提供者食谱之上的语法糖

  • Value Recipe是最简单的情况,您可以自己实例化服务并向注入器提供实例化值
  • Factory配方为Injector提供了一个工厂函数,它在需要实例化服务时调用。 调用时, 工厂函数创建并返回服务实例。 服务的依赖关系作为函数的参数注入。 因此,使用此配方可添加以下功能:
    • 能够使用其他服务(具有依赖性)
    • 服务初始化
    • 延迟/延迟初始化
  • 服务配方几乎与工厂配方相同,但这里Injector使用new运算符而不是工厂函数调用构造函数。
  • 提供者食谱通常是矫枉过正的 。 它允许您配置工厂的创建,从而增加了一层间接。

    只有在要为应用程序范围的配置公开API时才应使用Provider配方,该API必须在应用程序启动之前进行。 这通常只适用于可重用服务,其行为可能需要在应用程序之间略有不同。

  • Constant配方就像Value配方一样,除了它允许您定义配置阶段中可用的服务。 比使用Value配方创建的服务早。 与Values不同,它们不能使用decorator进行decorator
请参阅提供商文档




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

说我们有:

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

三者之间的区别在于:

  1. a的储值来自于跑步fn
  2. b的储值来自newING fn
  3. c的存储值来自首先通过newing 获取实例fn,然后运行$get实例的方法。

这意味着在AngularJS中有类似缓存对象的东西,每次注入的值只分配一次,当它们第一次注入时,其中:

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

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




正如几个人在这里正确指出的那样,工厂,提供商,服务,甚至价值和常数都是同一件事的版本。您可以将更一般的内容剖析provider到所有这些中。像这样:

这是这张图片来自的文章:




在与提供商玩游戏时我发现了一些有趣的东西

对于服务提供者而言,注射剂的可见性与服务和工厂的可见性不同。如果声明AngularJS为“常量”(例如myApp.constant('a', 'Robert');),则可以将其注入服务,工厂和提供程序。

但是如果你声明一个AngularJS“值”(例如。,myApp.value('b', {name: 'Jones'});),你可以将它注入服务和工厂,但不能注入提供者创建函数。但是,您可以将其注入$get为您的提供程序定义的函数中。AngularJS文档中提到了这一点,但很容易错过。您可以在值和常量方法部分的%提供页面上找到它。

http://jsfiddle.net/R2Frv/1/

<div ng-app="MyAppName">
    <div ng-controller="MyCtrl">
        <p>from Service: {{servGreet}}</p>
        <p>from Provider: {{provGreet}}</p>
    </div>
</div>
<script>
    var myApp = angular.module('MyAppName', []);

    myApp.constant('a', 'Robert');
    myApp.value('b', {name: 'Jones'});

    myApp.service('greetService', function(a,b) {
        this.greeter = 'Hi there, ' + a + ' ' + b.name;
    });

    myApp.provider('greetProvider', function(a) {
        this.firstName = a;
        this.$get = function(b) {
            this.lastName = b.name;
            this.fullName = this.firstName + ' ' + this.lastName;
            return this;
        };
    });

    function MyCtrl($scope, greetService, greetProvider) {
        $scope.servGreet = greetService.greeter;
        $scope.provGreet = greetProvider.fullName;
    }
</script>



对我来说,理解差异的最好和最简单的方法是:

var service, factory;
service = factory = function(injection) {}

AngularJS如何实例化特定组件(简化):

// service
var angularService = new service(injection);

// factory
var angularFactory = factory(injection);

因此,对于服务,成为AngularJS组件的是类的对象实例,它由服务声明函数表示。对于工厂,它是从工厂申报功能返回的结果。工厂的行为可能与服务相同:

var factoryAsService = function(injection) {
  return new function(injection) {
    // Service content
  }
}

最简单的思考方式如下:

  • 服务是一个单例对象实例。如果要为代码提供单例对象,请使用服务。
  • 工厂是一个班级。如果要为代码提供自定义类,请使用工厂(由于已经实例化,因此无法使用服务)。

工厂的“类”示例在评论中提供,以及提供商差异。




我的理解下面很简单。

工厂:您只需在工厂内创建一个对象并将其返回。

服务:

您只需要一个使用此关键字定义函数的标准函数。

提供者:

$get您定义了一个对象,它可用于获取返回数据的对象。




另外一个澄清是工厂可以创建函数/原语,而服务则不能。看看这个jsFiddle基于Epokk的:http://jsfiddle.net/skeller88/PxdSP/1351/

工厂返回一个可以调用的函数:

myApp.factory('helloWorldFromFactory', function() {
  return function() {
    return "Hello, World!";
  };
});

工厂还可以使用可以调用的方法返回一个对象:

myApp.factory('helloWorldFromFactory', function() {
  return {
    sayHello: function() {
      return "Hello, World!";
    }
  };
});

该服务返回一个对象,该对象具有可以调用的方法:

myApp.service('helloWorldFromService', function() {
  this.sayHello = function() {
     return "Hello, World!";
  };
});

有关详细信息,请参阅我在差异上写的帖子:http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/




所有的好答案已经。我想在服务工厂上增加几点。随着服务/工厂之间的差异。人们也可以有这样的问题:

  1. 我应该使用服务还是工厂?有什么不同?
  2. 他们是一样的还是有同样的行为?

让我们从服务和工厂之间的区别开始:

  1. 两者都是单身人士:每当Angular第一次将这些视为依赖时,它就会创建一个服务/工厂实例。创建实例后,将永久使用相同的实例。

  2. 可用于对具有行为的对象建模:它们都可以包含方法,内部状态变量等。虽然你编写代码的方式会有所不同。

服务:

服务是构造函数,Angular将通过调用new来实例化它yourServiceName()。这意味着一些事情。

  1. 函数和实例变量将是。的属性this
  2. 您不需要返回值。当Angular调用时new yourServiceName(,它将接收this包含您放置的所有属性的对象。

示例示例:

angular.service('MyService', function() {
  this.aServiceVariable = "Ved Prakash"
  this.aServiceMethod = function() {
    return //code
  };
});

当Angular将此MyService服务注入依赖于它的控制器时,该控制器将获得MyService可以调用函数的控件,例如MyService.aServiceMethod()。

小心this

由于构造的服务是一个对象,因此当它们被调用时,它内部的方法可以引用它:

angular.service('ScoreKeeper', function($http) {
  this.score = 0;

  this.getScore = function() {
    return this.score;
  };

  this.setScore = function(newScore) {
    this.score = newScore;
  };

  this.addOne = function() {
    this.score++;
  };
});

您可能很想调用ScoreKeeper.setScore一个promise链,例如,如果您通过从服务器中获取该分数来初始化该分数:$http.get('/score').then(ScoreKeeper.setScore).这样做的问题是ScoreKeeper.setScore将被this绑定调用null并且您将获得错误。更好的方法是$http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper))。无论您是否选择在服务方法中使用此方法,请小心如何调用它们。

从a返回一个值Service

由于JavaScript构造函数的工作方式,如果(ie, an Object)constructor函数返回复杂值,调用者将获取该Object而不是此实例。

这意味着您基本上可以从下面复制粘贴工厂示例,替换factoryservice,它将工作:

angular.service('MyService', function($http) {
  var api = {};

  api.aServiceMethod= function() {
    return $http.get('/users');
  };
  return api;
});

因此,当Angular使用新的MyService()构造您的服务时,它将获得该api对象而不是MyService实例。

这是任何复杂值(对象,函数)的行为,但不适用于基本类型。

工厂:

工厂是一个返回值的普通旧函数。返回值是注入依赖于工厂的东西的东西。Angular中的典型工厂模式是返回一个具有属性的对象,如下所示:

angular.factory('MyFactory', function($http) {
  var api = {};

  api.aFactoryMethod= function() {
    return $http.get('/users');
  };

  return api;
});

工厂依赖项的注入值是工厂的返回值,它不必是对象。它可能是一种功能

以上1和2个问题的答案:

在大多数情况下,只需坚持使用工厂的一切。他们的行为更容易理解。没有选择是否返回一个值,而且,如果你做错了,就不会引入错误。

不过,当我谈到将它们作为依赖项注入时,我仍将它们称为“服务”。

服务/工厂行为非常相似,有些人会说任何一个都很好。这有点真实,但我发现更容易遵循John Papa的风格指南的建议,只是坚持工厂。**




作为参考这个页面和docs.angularjs.org/guide/providers(自上次我看起来似乎有了很大的改进),我把以下真正的( - )世界演示放在一起,它使用了5种提供者中的4种; 价值,恒定,工厂和完整的供应商。

HTML:

<div ng-controller="mainCtrl as main">
    <h1>{{main.title}}*</h1>
    <h2>{{main.strapline}}</h2>
    <p>Earn {{main.earn}} per click</p>
    <p>You've earned {{main.earned}} by clicking!</p>
    <button ng-click="main.handleClick()">Click me to earn</button>
    <small>* Not actual money</small>
</div>

应用

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

// A CONSTANT is not going to change
app.constant('range', 100);

// A VALUE could change, but probably / typically doesn't
app.value('title', 'Earn money by clicking');
app.value('strapline', 'Adventures in ng Providers');

// A simple FACTORY allows us to compute a value @ runtime.
// Furthermore, it can have other dependencies injected into it such
// as our range constant.
app.factory('random', function randomFactory(range) {
    // Get a random number within the range defined in our CONSTANT
    return Math.random() * range;
});

// A PROVIDER, must return a custom type which implements the functionality 
// provided by our service (see what I did there?).
// Here we define the constructor for the custom type the PROVIDER below will 
// instantiate and return.
var Money = function(locale) {

    // Depending on locale string set during config phase, we'll
    // use different symbols and positioning for any values we 
    // need to display as currency
    this.settings = {
        uk: {
            front: true,
            currency: '£',
            thousand: ',',
            decimal: '.'
        },
        eu: {
            front: false,
            currency: '€',
            thousand: '.',
            decimal: ','
        }
    };

    this.locale = locale;
};

// Return a monetary value with currency symbol and placement, and decimal 
// and thousand delimiters according to the locale set in the config phase.
Money.prototype.convertValue = function(value) {

    var settings = this.settings[this.locale],
        decimalIndex, converted;

    converted = this.addThousandSeparator(value.toFixed(2), settings.thousand);

    decimalIndex = converted.length - 3;

    converted = converted.substr(0, decimalIndex) +
        settings.decimal +
        converted.substr(decimalIndex + 1);    

    converted = settings.front ?
            settings.currency + converted : 
            converted + settings.currency; 

    return converted;   
};

// Add supplied thousand separator to supplied value
Money.prototype.addThousandSeparator = function(value, symbol) {
   return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, symbol);
};

// PROVIDER is the core recipe type - VALUE, CONSTANT, SERVICE & FACTORY
// are all effectively syntactic sugar built on top of the PROVIDER construct
// One of the advantages of the PROVIDER is that we can configure it before the
// application starts (see config below).
app.provider('money', function MoneyProvider() {

    var locale;

    // Function called by the config to set up the provider
    this.setLocale = function(value) {
        locale = value;   
    };

    // All providers need to implement a $get method which returns
    // an instance of the custom class which constitutes the service
    this.$get = function moneyFactory() {
        return new Money(locale);
    };
});

// We can configure a PROVIDER on application initialisation.
app.config(['moneyProvider', function(moneyProvider) {
    moneyProvider.setLocale('uk');
    //moneyProvider.setLocale('eu'); 
}]);

// The ubiquitous controller
app.controller('mainCtrl', function($scope, title, strapline, random, money) {

    // Plain old VALUE(s)
    this.title = title;
    this.strapline = strapline;

    this.count = 0;

    // Compute values using our money provider    
    this.earn = money.convertValue(random); // random is computed @ runtime
    this.earned = money.convertValue(0);

    this.handleClick = function() { 
        this.count ++;
        this.earned = money.convertValue(random * this.count);
    };
});

工作demo




阅读完所有这些帖子之后,它给我带来了更多的困惑..但仍然都是值得信息的......最后我发现下面的表格会给出简单的比较信息

  • 注入器使用配方来创建两种类型的对象:服务和专用对象
  • 有五种配方类型定义了如何创建对象:Value,Factory,Service,Provider和Constant。
  • 工厂和服务是最常用的食谱。它们之间的唯一区别是Service配方更适合自定义类型的对象,而Factory可以生成JavaScript原语和函数。
  • 提供者配方是核心配方类型,所有其他配方只是语法糖。
  • 提供者是最复杂的配方类型。除非您正在构建需要全局配置的可重用代码,否则您不需要它。
  • 除Controller外的所有特殊用途对象都是通过工厂配方定义的。

并且对于初学者的理解: -这可能不正确的用例,但在高级别,这是这三个用例。

  1. 如果要在角度模块中使用配置功能,则应创建为提供者

angular.module('myApp').config(function($testProvider){
$testProvider.someFunction();
})

  1. Ajax调用或第三方集成需要服务
  2. 对于数据操作,将其创建为工厂

对于基本方案,工厂和服务的行为相同。




派对迟到了。但我认为这对于谁愿意学习(或明确)使用工厂,服务和提供商方法开发Angular JS Custom Services更有帮助。

我看到了这个视频,它清楚地解释了开发AngularJS Custom Services的工厂,服务和提供商方法:

https://www.youtube.com/watch?v=oUXku28ex-M

源代码:http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-servicehttp://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service

此处发布的代码直接从上述来源复制,以使读者受益。

基于“工厂”的自定义服务的代码如下(与同步和异步版本以及调用http服务一起使用):

var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcFactory',
  function($scope, calcFactory) {
    $scope.a = 10;
    $scope.b = 20;

    $scope.doSum = function() {
      //$scope.sum = calcFactory.getSum($scope.a, $scope.b); //synchronous
      calcFactory.getSum($scope.a, $scope.b, function(r) { //aynchronous
        $scope.sum = r;
      });
    };

  }
]);

app.factory('calcFactory', ['$http', '$log',
  function($http, $log) {
    $log.log("instantiating calcFactory..");
    var oCalcService = {};

    //oCalcService.getSum = function(a,b){
    //	return parseInt(a) + parseInt(b);
    //};

    //oCalcService.getSum = function(a, b, cb){
    //	var s = parseInt(a) + parseInt(b);
    //	cb(s);
    //};

    oCalcService.getSum = function(a, b, cb) { //using http service

      $http({
        url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
        method: 'GET'
      }).then(function(resp) {
        $log.log(resp.data);
        cb(resp.data);
      }, function(resp) {
        $log.error("ERROR occurred");
      });
    };

    return oCalcService;
  }
]);

自定义服务的“服务”方法代码(这与“工厂”非常相似,但与语法不同):

var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
	$scope.a = 10;
	$scope.b = 20;

	$scope.doSum = function(){
		//$scope.sum = calcService.getSum($scope.a, $scope.b);
		
		calcService.getSum($scope.a, $scope.b, function(r){
			$scope.sum = r;
		});		
	};

}]);

app.service('calcService', ['$http', '$log', function($http, $log){
	$log.log("instantiating calcService..");
	
	//this.getSum = function(a,b){
	//	return parseInt(a) + parseInt(b);
	//};

	//this.getSum = function(a, b, cb){
	//	var s = parseInt(a) + parseInt(b);
	//	cb(s);
	//};

	this.getSum = function(a, b, cb){
		$http({
			url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
			method: 'GET'
		}).then(function(resp){
			$log.log(resp.data);
			cb(resp.data);
		},function(resp){
			$log.error("ERROR occurred");
		});
	};

}]);

自定义服务的“提供者”方法的代码(如果您想开发可配置的服务,这是必要的):

var app = angular.module("app", []);
app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
	$scope.a = 10;
	$scope.b = 20;

	$scope.doSum = function(){
		//$scope.sum = calcService.getSum($scope.a, $scope.b);
		
		calcService.getSum($scope.a, $scope.b, function(r){
			$scope.sum = r;
		});		
	};

}]);

app.provider('calcService', function(){

	var baseUrl = '';

	this.config = function(url){
		baseUrl = url;
	};

	this.$get = ['$log', '$http', function($log, $http){
		$log.log("instantiating calcService...")
		var oCalcService = {};

		//oCalcService.getSum = function(a,b){
		//	return parseInt(a) + parseInt(b);
		//};

		//oCalcService.getSum = function(a, b, cb){
		//	var s = parseInt(a) + parseInt(b);
		//	cb(s);	
		//};

		oCalcService.getSum = function(a, b, cb){

			$http({
				url: baseUrl + '/Sum?a=' + a + '&b=' + b,
				method: 'GET'
			}).then(function(resp){
				$log.log(resp.data);
				cb(resp.data);
			},function(resp){
				$log.error("ERROR occurred");
			});
		};		

		return oCalcService;
	}];

});

app.config(['calcServiceProvider', function(calcServiceProvider){
	calcServiceProvider.config("http://localhost:4467");
}]);

最后,UI与上述任何服务一起使用:

<html>
<head>
	<title></title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js" ></script>
	<script type="text/javascript" src="t03.js"></script>
</head>
<body ng-app="app">
	<div ng-controller="emp">
		<div>
			Value of a is {{a}},
			but you can change
			<input type=text ng-model="a" /> <br>

			Value of b is {{b}},
			but you can change
			<input type=text ng-model="b" /> <br>

		</div>
		Sum = {{sum}}<br>
		<button ng-click="doSum()">Calculate</button>
	</div>
</body>
</html>




让我们以一种简单的方式讨论在AngularJS中处理业务逻辑的三种方式:( 受Yaakov的Coursera AngularJS课程的启发

服务

句法:

app.js

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

 ServiceExampleController.$inject = ['NameOfTheService'] //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;
     }     
}

的index.html

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

服务特色:

  1. Lazily Instantiated:如果没有注入,它将不会被实例化。因此要使用它必须将其注入模块。
  2. 单例:如果注入多个模块,则所有模块都只能访问一个特定实例。这就是在不同控制器之间共享数据非常方便的原因。

首先让我们来看看语法:

app.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();

工厂特点:

  1. 遵循工厂设计模式。工厂是生产新物体或功能的中心位置。
  2. 不仅可以生产单件,还可以定制服务。
  3. .service()方法是一个始终生成相同类型服务的工厂,它是一个单独的服务,并且没有任何简单的方法来配置它的行为。该.service()方法通常用作不需要任何配置的快捷方式。

提供商

让我们再次看一下Syntax:

angular.module('ProviderModule', [])
.controller('ProviderModuleController', ProviderModuleController)
.provider('ServiceProvider', ServiceProvider)
.config(Config); //optional

Config.$inject = ['ServiceProvider'];
function Config(ServiceProvider) {
  ServiceProvider.defaults.maxItems = 10; //some default value
}


ProviderModuleController.$inject = ['ServiceProvider'];
function ProviderModuleController(ServiceProvider) {
  //some methods
}

function ServiceProvider() {
  var provider = this;

  provider.defaults = {
    maxItems: 10
  };

  provider.$get = function () {
    var someList = new someListService(provider.defaults.maxItems);

    return someList;
  };
}

}

提供者的特点:

  1. Provider是在Angular中创建服务的最灵活方法。
  2. 我们不仅可以创建一个可动态配置的工厂,而且在使用工厂时,使用提供程序方法,我们可以在整个应用程序的引导时自定义配置工厂一次。
  3. 然后,工厂可以在整个应用程序中使用自定义设置。换句话说,我们可以在应用程序启动之前配置此工厂。事实上,在角度文档中,提到了当我们使用其中一个.service或多个.factory方法配置服务时,提供者方法实际上是在幕后执行的。
  4. $get函数直接附加到提供程序实例。该功能是工厂功能。换句话说,它就像我们用来.factory方法提供的那个。在该功能中,我们创建自己的服务。这个$get属性是一个函数,它使提供者成为提供者AngularJS希望提供者有一个$ get属性,其值是Angular将其视为工厂函数的函数。但是,整个提供程序设置非常特殊的原因是我们可以config在服务提供程序中提供一些对象,并且通常会带有我们以后可以在步骤中覆盖的默认值,我们可以在其中配置整个应用程序。



从本质上讲,提供商,工厂和服务都是服务。工厂是服务的一个特例,只需要一个$ get()函数,允许你用更少的代码编写它。

服务,工厂和供应商之间的主要区别在于其复杂性。服务是最简单的形式,工厂更健壮,供应商可在运行时配置。

以下是何时使用每个的摘要:

工厂:您提供的价值需要根据其他数据计算。

服务:您正在使用方法返回一个对象。

提供程序:您希望能够在配置阶段配置将在创建之前创建的对象。在应用程序完全初始化之前,主要在应用程序配置中使用提供程序。




基于内存目的,控制器仅在需要时才被实例化,而在不需要时则被丢弃。因此,每次切换路径或重新加载页面时,Angular都会清理当前控制器。然而,服务提供了一种在应用程序的生命周期内保持数据的方法,同时它们也可以以一致的方式在不同的控制器上使用。

Angular为我们提供了三种创建和注册自己服务的方法。

1)工厂

2)服务

3)提供者

工厂:工厂是一个简单的功能,允许您在创建对象之前添加一些逻辑。它返回创建的对象。

它只是一个像类一样的函数集合。因此,当您使用构造函数时,它可以在不同的控制器中实例化。

服务:服务是一个构造函数,它使用new关键字创建对象。您可以使用此关键字向服务对象添加属性和函数。与工厂不同,它不会返回任何东西。

它是一个单例对象。需要在整个应用程序中共享单个对象时使用它。例如,经过身份验证的用户详细信息

提供者:提供者用于创建可配置的服务对象。它使用$ get()函数返回值。

在服务对象可用之前,需要为服务对象提供模块化配置。

运行以下代码并查看输出。

<!DOCTYPE html>
<html ng-app="app">
<head>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
    <meta charset=utf-8 />
    <title>JS Bin</title>
</head>
<body ng-controller="MyCtrl">
    {{serviceOutput}}
    <br/><br/>
    {{factoryOutput}}
    <br/><br/>
    {{providerOutput}}
    <script>
        var app = angular.module( 'app', [] );
        var MyFunc = function() {
            this.name = "default name";
            this.$get = function() {
                this.name = "new name"
                return "Hello from MyFunc.$get(). this.name = " + this.name;
            };
            return "Hello from MyFunc(). this.name = " + this.name;
        };
        // returns the actual function
        app.service( 'myService', MyFunc );
        // returns the function's return value
        app.factory( 'myFactory', MyFunc );
        // returns the output of the function's $get function
        app.provider( 'myProv', MyFunc );
        function MyCtrl( $scope, myService, myFactory, myProv ) {
            $scope.serviceOutput = "myService = " + myService;
            $scope.factoryOutput = "myFactory = " + myFactory;
            $scope.providerOutput = "myProvider = " + myProv;
        }
    </script>
</body>
</html>




Related