etc./StackOverFlow

AngularJS: 서비스 대 공급자 대 공장

청렴결백한 만능 재주꾼 2021. 10. 6. 03:01
반응형

질문자 :Lior


AngularJS에서 Service , ProviderFactory 의 차이점은 무엇입니까?



AngularJS 메일링 리스트에서 서비스 대 공장 대 공급자 및 주입 사용을 설명 하는 놀라운 스레드를 얻었습니다. 답변 컴파일:

서비스

구문: module.service( 'serviceName', function );
결과: serviceName을 주입 가능한 인수로 선언 하면 함수의 인스턴스가 제공됩니다. 즉, new FunctionYouPassedToService() 입니다.

공장

구문: module.factory( 'factoryName', function );
결과: factoryName을 주입 가능한 인수로 선언하면 module.factory에 전달된 함수 참조를 호출하여 반환되는 값이 제공됩니다.

공급자

구문: module.provider( 'providerName', function );
결과 : 당신이 제공됩니다 주사 인수로의 providerName를 선언 할 때 (new ProviderFunction()).$get() . 생성자 함수는 $get 메서드가 호출되기 전에 인스턴스화됩니다. ProviderFunction 은 module.provider에 전달된 함수 참조입니다.

공급자는 모듈 구성 단계에서 구성할 수 있다는 이점이 있습니다.

제공된 코드는 여기 를 참조하십시오.

Misko의 훌륭한 추가 설명은 다음과 같습니다.

 provide.value('a', 123); function Controller(a) { expect(a).toEqual(123); }

이 경우 인젝터는 단순히 값을 있는 그대로 반환합니다. 그러나 값을 계산하려면 어떻게 해야 합니까? 그런 다음 공장을 사용하십시오.

 provide.factory('b', function(a) { return a*2; }); function Controller(b) { expect(b).toEqual(246); }

그래서 factory 은 가치를 창출하는 역할을 하는 기능입니다. 팩토리 함수는 다른 종속성을 요청할 수 있습니다.

그러나 더 많은 OO를 원하고 Greeter라는 클래스가 있다면 어떻게 될까요?

 function Greeter(a) { this.greet = function() { return 'Hello ' + a; } }

그런 다음 인스턴스화하려면 다음을 작성해야합니다.

 provide.factory('greeter', function(a) { return new Greeter(a); });

그러면 다음과 같이 컨트롤러에 '인사'를 요청할 수 있습니다.

 function Controller(greeter) { expect(greeter instanceof Greeter).toBe(true); expect(greeter.greet()).toEqual('Hello 123'); }

그러나 그것은 너무 말이 많습니다. 이것을 작성하는 더 짧은 방법은 provider.service('greeter', Greeter);

그러나 주입 전에 Greeter 클래스를 구성하려면 어떻게 해야 할까요? 그러면 우리는 쓸 수 있습니다.

 provide.provider('greeter2', function() { var salutation = 'Hello'; this.setSalutation = function(s) { salutation = s; } function Greeter(a) { this.greet = function() { return salutation + ' ' + a; } } this.$get = function(a) { return new Greeter(a); }; });

그러면 다음과 같이 할 수 있습니다.

 angular.module('abc', []).config(function(greeter2Provider) { greeter2Provider.setSalutation('Halo'); }); function Controller(greeter2) { expect(greeter2.greet()).toEqual('Halo 123'); }

참고로 service , factoryvalue 는 모두 provider에서 파생됩니다.

 provider.service = function(name, Class) { provider.provide(name, function() { this.$get = function($injector) { return $injector.instantiate(Class); }; }); } provider.factory = function(name, factory) { provider.provide(name, function() { this.$get = function($injector) { return $injector.invoke(factory); }; }); } provider.value = function(name, value) { provider.factory(name, function() { return value; }); };

Community Wiki

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>


EpokK

TL;DR

1) Factory 를 사용할 때 객체를 생성하고 속성을 추가한 다음 동일한 객체를 반환합니다. 이 팩토리를 컨트롤러에 전달하면 개체의 해당 속성을 이제 팩토리를 통해 해당 컨트롤러에서 사용할 수 있습니다.

 app.controller('myFactoryCtrl', function($scope, myFactory){ $scope.artist = myFactory.getArtist(); }); app.factory('myFactory', function(){ var _artist = 'Shakira'; var service = {}; service.getArtist = function(){ return _artist; } return service; });


2) Service 를 사용할 때 AngularJS는 'new' 키워드를 사용하여 뒤에서 인스턴스화합니다. 이 때문에 'this'에 속성을 추가하면 서비스가 'this'를 반환합니다. 서비스를 컨트롤러에 전달할 때 'this'의 속성은 이제 서비스를 통해 해당 컨트롤러에서 사용할 수 있습니다.

 app.controller('myServiceCtrl', function($scope, myService){ $scope.artist = myService.getArtist(); }); app.service('myService', function(){ var _artist = 'Nelly'; this.getArtist = function(){ return _artist; } });



3) 공급자 는 .config() 함수에 전달할 수 있는 유일한 서비스입니다. 서비스 개체를 사용 가능하게 만들기 전에 모듈 전체 구성을 제공하려는 경우 공급자를 사용합니다.

 app.controller('myProvider', function($scope, myProvider){ $scope.artist = myProvider.getArtist(); $scope.data.thingFromConfig = myProvider.thingOnConfig; }); app.provider('myProvider', function(){ //Only the next two lines are available in the app.config() this._artist = ''; this.thingFromConfig = ''; this.$get = function(){ var that = this; return { getArtist: function(){ return that._artist; }, thingOnConfig: that.thingFromConfig } } }); app.config(function(myProviderProvider){ myProviderProvider.thingFromConfig = 'This was set in config'; });



비 TL;DR

1) 공장
팩토리는 서비스를 생성하고 구성하는 가장 보편적인 방법입니다. TL;DR이 말한 것보다 더 많은 것은 없습니다. 객체를 만들고 속성을 추가한 다음 동일한 객체를 반환하기만 하면 됩니다. 그런 다음 팩토리를 컨트롤러에 전달할 때 객체의 해당 속성은 이제 팩토리를 통해 해당 컨트롤러에서 사용할 수 있습니다. 더 광범위한 예가 아래에 있습니다.

 app.factory('myFactory', function(){ var service = {}; return service; });

이제 'myFactory'를 컨트롤러에 전달할 때 'service'에 연결하는 모든 속성을 사용할 수 있습니다.

이제 콜백 함수에 '비공개' 변수를 추가해 보겠습니다. 컨트롤러에서 직접 액세스할 수는 없지만 필요할 때 이러한 '개인' 변수를 변경할 수 있도록 '서비스'에 대한 일부 getter/setter 메서드를 결국 설정할 것입니다.

 app.factory('myFactory', function($http, $q){ var service = {}; var baseUrl = 'https://itunes.apple.com/search?term='; var _artist = ''; var _finalUrl = ''; var makeUrl = function(){ _artist = _artist.split(' ').join('+'); _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'; return _finalUrl } return service; });

여기서 우리는 이러한 변수/함수를 'service'에 연결하지 않는다는 것을 알 수 있습니다. 나중에 사용하거나 수정하기 위해 단순히 생성합니다.

  • baseUrl은 iTunes API에 필요한 기본 URL입니다.
  • _artist는 조회하려는 아티스트입니다.
  • _finalUrl은 iTunes를 호출할 최종 완성된 URL입니다.
  • makeUrl은 iTunes 친화적인 URL을 생성하고 반환하는 기능입니다.

이제 도우미/개인 변수와 함수가 준비되었으므로 'service' 개체에 몇 가지 속성을 추가해 보겠습니다. 우리가 '서비스'에 넣는 것은 무엇이든 'myFactory'를 전달하는 컨트롤러 내부에서 직접 사용할 수 있습니다.

단순히 아티스트를 반환하거나 설정하는 setArtist 및 getArtist 메서드를 만들 것입니다. 또한 생성된 URL로 iTunes API를 호출하는 메서드를 만들 것입니다. 이 메서드는 데이터가 iTunes API에서 반환되면 이행할 약속을 반환합니다. AngularJS에서 Promise를 사용한 경험이 많지 않다면 이에 대해 자세히 알아보는 것이 좋습니다.

아래 setArtist 는 아티스트를 허용하고 아티스트를 설정할 수 있도록 합니다. getArtist 는 아티스트를 반환합니다. callItunes는 먼저 $http 요청에 사용할 URL을 작성하기 위해 makeUrl()을 호출합니다. 그런 다음 Promise 객체를 설정하고 최종 URL로 $http 요청을 하고 $http가 promise를 반환하기 때문에 요청 후에 .success 또는 .error를 호출할 수 있습니다. 그런 다음 iTunes 데이터로 약속을 해결하거나 '오류가 있었습니다'라는 메시지와 함께 약속을 거부합니다.

 app.factory('myFactory', function($http, $q){ var service = {}; var baseUrl = 'https://itunes.apple.com/search?term='; var _artist = ''; var _finalUrl = ''; var makeUrl = function(){ _artist = _artist.split(' ').join('+'); _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK' return _finalUrl; } service.setArtist = function(artist){ _artist = artist; } service.getArtist = function(){ return _artist; } service.callItunes = function(){ makeUrl(); var deferred = $q.defer(); $http({ method: 'JSONP', url: _finalUrl }).success(function(data){ deferred.resolve(data); }).error(function(){ deferred.reject('There was an error') }) return deferred.promise; } return service; });

이제 우리 공장이 완성되었습니다. 이제 'myFactory'를 모든 컨트롤러에 주입할 수 있으며 서비스 개체(setArtist, getArtist 및 callItunes)에 연결한 메서드를 호출할 수 있습니다.

 app.controller('myFactoryCtrl', function($scope, myFactory){ $scope.data = {}; $scope.updateArtist = function(){ myFactory.setArtist($scope.data.artist); }; $scope.submitArtist = function(){ myFactory.callItunes() .then(function(data){ $scope.data.artistData = data; }, function(data){ alert(data); }) } });

위의 컨트롤러에서 우리는 'myFactory' 서비스를 주입하고 있습니다. 그런 다음 'myFactory'의 데이터를 사용하여 $scope 개체에 속성을 설정합니다. 위의 유일한 까다로운 코드는 이전에 약속을 처리한 적이 없는 경우입니다. callItunes가 약속을 반환하기 때문에 .then() 메서드를 사용할 수 있으며 약속이 iTunes 데이터로 이행된 후에만 $scope.data.artistData를 설정할 수 있습니다. 컨트롤러가 매우 '얇다는' 것을 알 수 있습니다(좋은 코딩 방법입니다). 모든 논리 및 영구 데이터는 컨트롤러가 아니라 서비스에 있습니다.

2) 서비스
아마도 서비스 생성을 다룰 때 알아야 할 가장 큰 것은 'new' 키워드로 인스턴스화된다는 것입니다. JavaScript 전문가에게 이것은 코드의 본질에 대한 큰 힌트를 줄 것입니다. JavaScript에 대한 배경 지식이 제한적이거나 'new' 키워드가 실제로 무엇을 하는지 잘 모르는 사람들을 위해 궁극적으로 서비스의 특성을 이해하는 데 도움이 될 몇 가지 JavaScript 기본 사항을 검토해 보겠습니다.

'new' 키워드로 함수를 호출할 때 발생하는 변경 사항을 실제로 보려면 함수를 생성하고 'new' 키워드로 호출한 다음 인터프리터가 'new' 키워드를 볼 때 수행하는 작업을 보여줍시다. 최종 결과는 둘 다 동일할 것입니다.

먼저 생성자를 생성해 보겠습니다.

 var Person = function(name, age){ this.name = name; this.age = age; }

이것은 전형적인 JavaScript 생성자 함수입니다. 이제 'new' 키워드를 사용하여 Person 함수를 호출할 때마다 'this'는 새로 생성된 객체에 바인딩됩니다.

이제 Person의 프로토타입에 메서드를 추가하여 Person '클래스'의 모든 인스턴스에서 사용할 수 있도록 합시다.

 Person.prototype.sayName = function(){ alert('My name is ' + this.name); }

이제 프로토타입에 sayName 함수를 넣었기 때문에 Person의 모든 인스턴스는 해당 인스턴스의 이름을 알리기 위해 sayName 함수를 호출할 수 있습니다.

이제 프로토타입에 Person 생성자 함수와 sayName 함수가 있으므로 실제로 Person의 인스턴스를 만든 다음 sayName 함수를 호출해 보겠습니다.

 var tyler = new Person('Tyler', 23); tyler.sayName(); //alerts 'My name is Tyler'

따라서 Person 생성자를 만들고 프로토타입에 함수를 추가하고 Person 인스턴스를 만들고 프로토타입에서 함수를 호출하는 코드는 모두 다음과 같습니다.

 var Person = function(name, age){ this.name = name; this.age = age; } Person.prototype.sayName = function(){ alert('My name is ' + this.name); } var tyler = new Person('Tyler', 23); tyler.sayName(); //alerts 'My name is Tyler'

이제 JavaScript에서 'new' 키워드를 사용할 때 실제로 어떤 일이 발생하는지 살펴보겠습니다. 첫 번째로 주의해야 할 점은 이 예에서 'new'를 사용한 후 'tyler'에 대해 마치 객체인 것처럼 메서드(sayName)를 호출할 수 있다는 것입니다. 따라서 먼저 코드에서 볼 수 있는지 여부에 관계없이 Person 생성자가 객체를 반환한다는 것을 압니다. 둘째, 우리는 sayName 함수가 Person 인스턴스에 직접 있지 않고 프로토타입에 있기 때문에 Person 함수가 반환하는 객체는 실패한 조회에서 프로토타입에 위임해야 한다는 것을 알고 있습니다. 더 간단한 용어로, tyler.sayName()을 호출하면 인터프리터가 "좋아요, 방금 만든 'tyler' 객체를 살펴보고 sayName 함수를 찾은 다음 호출하겠습니다. 잠깐만요. 여기에서는 보이지 않습니다. 이름과 나이만 표시됩니다. 프로토타입을 확인하겠습니다. 네, 프로토타입에 있는 것 같으니 전화를 드리겠습니다.”

아래는 자바스크립트에서 'new' 키워드가 실제로 하는 일에 대해 생각해 볼 수 있는 코드입니다. 기본적으로 위 단락의 코드 예제입니다. '인터프리터 보기' 또는 인터프리터가 메모 내부에 코드를 보는 방식을 넣었습니다.

 var Person = function(name, age){ //The below line creates an object(obj) that will delegate to the person's prototype on failed lookups. //var obj = Object.create(Person.prototype); //The line directly below this sets 'this' to the newly created object //this = obj; this.name = name; this.age = age; //return this; }

이제 'new' 키워드가 JavaScript에서 실제로 무엇을 하는지에 대한 지식을 얻었으므로 AngularJS에서 서비스를 만드는 것이 더 이해하기 쉬울 것입니다.

서비스를 생성할 때 가장 이해해야 할 것은 서비스가 'new' 키워드로 인스턴스화된다는 것을 아는 것입니다. 그 지식을 위의 예와 결합하면 이제 서비스 자체에서 반환되는 'this'에 직접 속성과 메서드를 연결한다는 사실을 인식해야 합니다. 이를 실제로 살펴보겠습니다.

원래 Factory 예제에서 했던 것과는 달리 객체를 생성한 다음 해당 객체를 반환할 필요가 없습니다. 이전에 여러 번 언급했듯이 'new' 키워드를 사용하여 인터프리터가 해당 객체를 만들고 위임하도록 하기 때문입니다. 프로토타입이고 작업을 수행할 필요 없이 반환합니다.

먼저 'private' 및 helper 함수를 생성해 보겠습니다. 우리 공장에서 똑같은 일을 했기 때문에 이것은 매우 친숙해 보일 것입니다. 여기에서는 각 행이 하는 일을 설명하지 않겠습니다. 공장 예에서 그렇게 했기 때문입니다. 혼란스러우면 공장 예를 다시 읽으십시오.

 app.service('myService', function($http, $q){ var baseUrl = 'https://itunes.apple.com/search?term='; var _artist = ''; var _finalUrl = ''; var makeUrl = function(){ _artist = _artist.split(' ').join('+'); _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK' return _finalUrl; } });

이제 컨트롤러에서 사용할 수 있는 모든 메서드를 'this'에 연결합니다.

 app.service('myService', function($http, $q){ var baseUrl = 'https://itunes.apple.com/search?term='; var _artist = ''; var _finalUrl = ''; var makeUrl = function(){ _artist = _artist.split(' ').join('+'); _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK' return _finalUrl; } this.setArtist = function(artist){ _artist = artist; } this.getArtist = function(){ return _artist; } this.callItunes = function(){ makeUrl(); var deferred = $q.defer(); $http({ method: 'JSONP', url: _finalUrl }).success(function(data){ deferred.resolve(data); }).error(function(){ deferred.reject('There was an error') }) return deferred.promise; } });

이제 우리 공장에서와 같이 setArtist, getArtist 및 callItunes는 myService를 전달하는 컨트롤러에서 사용할 수 있습니다. 다음은 myService 컨트롤러입니다(공장 컨트롤러와 거의 동일함).

 app.controller('myServiceCtrl', function($scope, myService){ $scope.data = {}; $scope.updateArtist = function(){ myService.setArtist($scope.data.artist); }; $scope.submitArtist = function(){ myService.callItunes() .then(function(data){ $scope.data.artistData = data; }, function(data){ alert(data); }) } });

앞서 언급했듯이 'new'가 무엇을 하는지 제대로 이해하면 서비스는 AngularJS의 팩토리와 거의 동일합니다.

3) 제공자

제공자에 대해 기억해야 할 가장 큰 점은 제공자가 애플리케이션의 app.config 부분에 전달할 수 있는 유일한 서비스라는 것입니다. 이는 애플리케이션의 다른 모든 곳에서 사용할 수 있기 전에 서비스 개체의 일부를 변경해야 하는 경우 매우 중요합니다. Services/Factories와 매우 유사하지만 몇 가지 차이점이 있습니다.

먼저 서비스 및 공장과 유사한 방식으로 공급자를 설정했습니다. 아래 변수는 'private' 및 helper 함수입니다.

 app.provider('myProvider', function(){ var baseUrl = 'https://itunes.apple.com/search?term='; var _artist = ''; var _finalUrl = ''; //Going to set this property on the config function below. this.thingFromConfig = ''; var makeUrl = function(){ _artist = _artist.split(' ').join('+'); _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK' return _finalUrl; } }

*위 코드의 일부가 혼동되는 경우 다시 한 번 더 자세히 설명하는 Factory 섹션을 확인하세요.

공급자는 세 개의 섹션이 있는 것으로 생각할 수 있습니다. 첫 번째 섹션은 나중에 수정/설정될 '비공개' 변수/함수입니다(위에 표시됨). 두 번째 섹션은 app.config 함수에서 사용할 수 있는 변수/함수이므로 다른 곳에서 사용할 수 있기 전에 변경할 수 있습니다(위에 표시됨). 이러한 변수는 'this' 키워드에 연결해야 합니다. 이 예에서는 'thingFromConfig'만 app.config에서 변경할 수 있습니다. 세 번째 섹션(아래 표시)은 'myProvider' 서비스를 특정 컨트롤러에 전달할 때 컨트롤러에서 사용할 수 있는 모든 변수/함수입니다.

Provider로 서비스를 생성할 때 컨트롤러에서 사용할 수 있는 유일한 속성/메소드는 $get() 함수에서 반환되는 속성/메서드입니다. 아래 코드는 'this'에 $get을 넣습니다(이는 결국 해당 함수에서 반환될 것임을 알고 있음). 이제 해당 $get 함수는 컨트롤러에서 사용할 수 있는 모든 메서드/속성을 반환합니다. 다음은 코드 예입니다.

 this.$get = function($http, $q){ return { callItunes: function(){ makeUrl(); var deferred = $q.defer(); $http({ method: 'JSONP', url: _finalUrl }).success(function(data){ deferred.resolve(data); }).error(function(){ deferred.reject('There was an error') }) return deferred.promise; }, setArtist: function(artist){ _artist = artist; }, getArtist: function(){ return _artist; }, thingOnConfig: this.thingFromConfig } }

이제 전체 공급자 코드는 다음과 같습니다.

 app.provider('myProvider', function(){ var baseUrl = 'https://itunes.apple.com/search?term='; var _artist = ''; var _finalUrl = ''; //Going to set this property on the config function below this.thingFromConfig = ''; var makeUrl = function(){ _artist = _artist.split(' ').join('+'); _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK' return _finalUrl; } this.$get = function($http, $q){ return { callItunes: function(){ makeUrl(); var deferred = $q.defer(); $http({ method: 'JSONP', url: _finalUrl }).success(function(data){ deferred.resolve(data); }).error(function(){ deferred.reject('There was an error') }) return deferred.promise; }, setArtist: function(artist){ _artist = artist; }, getArtist: function(){ return _artist; }, thingOnConfig: this.thingFromConfig } } });

이제 우리 공장 및 서비스에서와 마찬가지로 setArtist, getArtist 및 callItunes는 myProvider를 전달하는 컨트롤러에서 사용할 수 있습니다. 다음은 myProvider 컨트롤러입니다(공장/서비스 컨트롤러와 거의 동일).

 app.controller('myProviderCtrl', function($scope, myProvider){ $scope.data = {}; $scope.updateArtist = function(){ myProvider.setArtist($scope.data.artist); }; $scope.submitArtist = function(){ myProvider.callItunes() .then(function(data){ $scope.data.artistData = data; }, function(data){ alert(data); }) } $scope.data.thingFromConfig = myProvider.thingOnConfig; });

앞에서 언급했듯이 Provider를 사용하여 서비스를 만드는 요점은 최종 개체가 나머지 응용 프로그램에 전달되기 전에 app.config 함수를 통해 일부 변수를 변경할 수 있다는 것입니다. 그 예를 살펴보겠습니다.

 app.config(function(myProviderProvider){ //Providers are the only service you can pass into app.config myProviderProvider.thingFromConfig = 'This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works'; });

이제 'thingFromConfig'가 공급자에서 빈 문자열로 표시되는 것을 볼 수 있지만 DOM에 표시되면 '이 문장은 설정되었습니다...'가 됩니다.


Tyler McGinnis

모든 서비스는 싱글톤입니다 . 앱당 한 번 인스턴스화됩니다. 프리미티브, 객체 리터럴, 함수 또는 사용자 정의 유형의 인스턴스이든 상관없이 모든 유형 이 될 수 있습니다.

value , factory , service , constantprovider 메소드는 모두 제공자입니다. 그들은 인젝터에게 서비스를 인스턴스화하는 방법을 가르칩니다.

가장 장황하지만 가장 포괄적인 것은 제공자 레시피입니다. 나머지 4가지 레시피 유형(Value, Factory, Service 및 Constant )은 공급자 레시피에 추가된 구문적 설탕일 뿐입니다 .

  • Value Recipe 는 서비스를 직접 인스턴스화하고 인스턴스화된 값 을 인젝터에 제공하는 가장 간단한 경우입니다.
  • 팩토리 레시피 는 인젝터가 서비스를 인스턴스화해야 할 때 호출하는 팩토리 기능을 제공합니다. 호출되면 팩토리 함수 는 서비스 인스턴스를 생성하고 반환합니다. 서비스의 종속성은 함수의 인수로 주입됩니다. 따라서 이 레시피를 사용하면 다음 기능이 추가됩니다.
    • 다른 서비스를 사용할 수 있는 능력(종속성 있음)
    • 서비스 초기화
    • 지연/지연 초기화
  • 서비스 레시피 는 팩토리 레시피와 거의 동일하지만 여기서 인젝터는 팩토리 함수 대신 new 연산자를 사용 하여 생성자를 호출합니다.
  • 공급자 레시피 는 일반적으로 과도 합니다. 팩토리 생성을 구성할 수 있도록 하여 간접 계층을 하나 더 추가합니다.

응용 프로그램이 시작되기 전에 이루어져야 하는 응용 프로그램 전체 구성을 위한 API를 노출하려는 경우에만 공급자 레시피를 사용해야 합니다. 이것은 일반적으로 동작이 애플리케이션마다 약간씩 달라야 할 수 있는 재사용 가능한 서비스에만 관심이 있습니다.


Community Wiki

AngularJS 팩토리, 서비스 및 제공자 이해

이들 모두는 재사용 가능한 싱글톤 객체를 공유하는 데 사용됩니다. 앱/다양한 구성 요소/모듈에서 재사용 가능한 코드를 공유하는 데 도움이 됩니다.

문서 서비스/공장에서 :

  • 지연 인스턴스화 – Angular는 애플리케이션 구성 요소가 종속된 경우에만 서비스/팩토리를 인스턴스화합니다.
  • 싱글톤 – 서비스에 종속된 각 구성 요소는 서비스 팩토리에서 생성된 단일 인스턴스에 대한 참조를 얻습니다.

공장

팩토리는 객체를 생성하기 전에 로직을 조작/추가하면 새로 생성된 객체가 반환되는 기능입니다.

 app.factory('MyFactory', function() { var serviceObj = {}; //creating an object with methods/functions or variables serviceObj.myFunction = function() { //TO DO: }; //return that object return serviceObj; });

용법

클래스와 같은 기능 모음일 수 있습니다. 따라서 컨트롤러/팩토리/지시 기능 내부에 삽입할 때 다른 컨트롤러에서 인스턴스화할 수 있습니다. 앱당 한 번만 인스턴스화됩니다.

서비스

단순히 서비스를 보면서 어레이 프로토타입에 대해 생각하십시오. 서비스는 'new' 키워드를 사용하여 새 객체를 인스턴스화하는 기능입니다. this 키워드를 사용하여 서비스 개체에 속성 및 기능을 추가할 수 있습니다. 팩토리와 달리 아무 것도 반환하지 않습니다(메소드/속성이 포함된 개체를 반환함).

 app.service('MyService', function() { //directly binding events to this context this.myServiceFunction = function() { //TO DO: }; });

용법

응용 프로그램 전체에서 단일 개체를 공유해야 할 때 사용합니다. 예를 들어 인증된 사용자 세부 정보, 공유 가능한 방법/데이터, 유틸리티 기능 등

공급자

공급자는 구성 가능한 서비스 개체를 만드는 데 사용됩니다. config 기능에서 서비스 설정을 구성할 수 있습니다. $get() 함수를 사용하여 값을 반환합니다. $get 함수는 실행 단계에서 각도로 실행됩니다.

 app.provider('configurableService', function() { var name = ''; //this method can be be available at configuration time inside app.config. this.setName = function(newName) { name = newName; }; this.$get = function() { var getName = function() { return name; }; return { getName: getName //exposed object to where it gets injected. }; }; });

용법

서비스 개체를 사용 가능하게 만들기 전에 모듈 단위 구성을 제공해야 하는 경우 dev , stage 또는 prod 와 같은 환경을 기반으로 API URL을 설정하려고 한다고 가정합니다.

노트

Angular의 구성 단계에서는 공급자만 사용할 수 있으며 서비스 및 공장은 사용할 수 없습니다.

이것이 Factory, Service 및 Provider에 대한 이해를 돕기를 바랍니다.


Pankaj Parkar

저에게 계시는 모든 것이 같은 방식으로 작동한다는 것을 깨달았을 때 나타났습니다. 무언가를 한 번 실행하고 얻은 값을 저장한 다음 종속성 주입을 통해 참조할 때 동일한 저장된 값 을 토해내는 것입니다.

우리가 가지고 있다고 가정해 봅시다:

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

세 가지의 차이점은 다음과 같습니다.

  1. a fn 을 실행하여 가져옵니다.
  2. b 의 저장된 값은 new fn 에서 가져옵니다.
  3. c 의 저장된 값은 먼저 new ing fn 인스턴스를 가져온 다음 해당 인스턴스 $get 메서드를 실행하여 가져옵니다.

이는 AngularJS 내부에 캐시 객체와 같은 것이 있음을 의미합니다. 각 주입의 값은 처음 주입되었을 때 한 번만 할당되며 다음 위치에서:

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

이것이 우리가 서비스에서 this 사용하고 공급자에서 this.$get


Lucia

서비스 대 공급자 대 공장:

나는 그것을 간단하게 유지하려고 노력한다. 기본적인 JavaScript 개념에 관한 것입니다.

먼저 AngularJS의 서비스 에 대해 이야기합시다!

서비스란 무엇입니까? AngularJS에서 서비스 는 유용한 메서드나 속성을 저장할 수 있는 싱글톤 JavaScript 객체에 불과합니다. 이 싱글톤 객체는 ngApp(Angular 앱) 단위로 생성되며 현재 앱 내의 모든 컨트롤러 간에 공유됩니다. Angularjs는 서비스 개체를 인스턴스화할 때 이 서비스 개체를 고유한 서비스 이름으로 등록합니다. 따라서 서비스 인스턴스가 필요할 때마다 Angular는 레지스트리에서 이 서비스 이름을 검색하고 서비스 개체에 대한 참조를 반환합니다. 서비스 개체에서 메서드를 호출하고 속성에 액세스할 수 있도록 합니다. 컨트롤러의 범위 개체에 속성, 메서드를 넣을 수도 있는지 여부에 대한 질문이 있을 수 있습니다! 그렇다면 왜 서비스 객체가 필요합니까? 답은 서비스가 여러 컨트롤러 범위에서 공유된다는 것입니다. 컨트롤러의 범위 개체에 일부 속성/메서드를 넣으면 현재 범위에서만 사용할 수 있습니다. 그러나 서비스 개체에 대한 메서드, 속성을 정의하면 전역적으로 사용할 수 있으며 해당 서비스를 주입하여 모든 컨트롤러 범위에서 액세스할 수 있습니다.

따라서 세 개의 컨트롤러 범위가 있는 경우 controllerA, controllerB 및 controllerC라고 하면 모두 동일한 서비스 인스턴스를 공유합니다.

 <div ng-controller='controllerA'> <!-- controllerA scope --> </div> <div ng-controller='controllerB'> <!-- controllerB scope --> </div> <div ng-controller='controllerC'> <!-- controllerC scope --> </div>

서비스를 만드는 방법?

AngularJS는 서비스를 등록하는 다양한 방법을 제공합니다. 여기서 우리는 세 가지 방법에 집중할 것입니다. factory(..),service(..),provider(..);

코드 참조를 위해 이 링크를 사용하십시오

공장 기능:

아래와 같이 팩토리 함수를 정의할 수 있습니다.

 factory('serviceName',function fnFactory(){ return serviceInstance;})

AngularJS는 두 개의 매개변수인 serviceName과 JavaScript 함수를 사용하는 'factory('serviceName', fnFactory)' 메서드를 제공합니다. Angular는 아래와 같이 fnFactory() 함수를 호출하여 서비스 인스턴스를 생성합니다.

 var serviceInstace = fnFactory();

전달된 함수는 개체를 정의하고 해당 개체를 반환할 수 있습니다. AngularJS는 단순히 첫 번째 인수로 전달되는 변수에 대한 이 객체 참조를 저장합니다. fnFactory에서 반환되는 모든 것은 serviceInstance에 바인딩됩니다. object 를 반환하는 대신 함수, 값 등을 반환할 수도 있습니다. 반환할 항목은 서비스 인스턴스에서 사용할 수 있습니다.

예시:

 var app= angular.module('myApp', []); //creating service using factory method app.factory('factoryPattern',function(){ var data={ 'firstName':'Tom', 'lastName':' Cruise', greet: function(){ console.log('hello!' + this.firstName + this.lastName); } }; //Now all the properties and methods of data object will be available in our service object return data; });

서비스 기능:

 service('serviceName',function fnServiceConstructor(){})

다른 방법으로 서비스를 등록할 수 있습니다. 유일한 차이점은 AngularJS가 서비스 객체를 인스턴스화하려고 시도하는 방식입니다. 이번에 angular는 'new' 키워드를 사용하고 아래와 같이 생성자 함수를 호출합니다.

 var serviceInstance = new fnServiceConstructor();

생성자 함수에서 서비스 객체에 속성/메소드를 추가하기 위해 'this' 키워드를 사용할 수 있습니다. 예시:

 //Creating a service using the service method var app= angular.module('myApp', []); app.service('servicePattern',function(){ this.firstName ='James'; this.lastName =' Bond'; this.greet = function(){ console.log('My Name is '+ this.firstName + this.lastName); }; });

제공자 기능:

Provider() 함수는 서비스를 생성하는 또 다른 방법입니다. 사용자에게 인사 메시지를 표시하는 서비스를 만드는 데 관심이 있습니다. 그러나 우리는 또한 사용자가 자신의 인사말 메시지를 설정할 수 있는 기능을 제공하고자 합니다. 기술적인 측면에서 우리는 구성 가능한 서비스를 만들고 싶습니다. 어떻게 하면 될까요? 앱이 사용자 정의 인사말 메시지를 전달할 수 있고 Angularjs가 서비스 인스턴스를 생성하는 factory/constructor 함수에서 사용할 수 있도록 하는 방법이 있어야 합니다. 이러한 경우 provider() 함수가 작업을 수행합니다. provider() 함수를 사용하여 구성 가능한 서비스를 만들 수 있습니다.

아래와 같이 공급자 구문을 사용하여 구성 가능한 서비스를 만들 수 있습니다.

 /*step1:define a service */ app.provider('service',function serviceProviderConstructor(){}); /*step2:configure the service */ app.config(function configureService(serviceProvider){});

공급자 구문은 내부적으로 어떻게 작동합니까?

1.Provider 객체는 provider 함수에서 정의한 생성자 함수를 사용하여 생성됩니다.

 var serviceProvider = new serviceProviderConstructor();

2. app.config()에서 전달한 함수가 실행됩니다. 이를 구성 단계라고 하며 여기에서 서비스를 사용자 정의할 수 있습니다.

 configureService(serviceProvider);

3. 마지막으로 serviceProvider의 $get 메소드를 호출하여 서비스 인스턴스를 생성한다.

 serviceInstance = serviceProvider.$get()

제공 구문을 사용하여 서비스를 생성하기 위한 샘플 코드:

 var app= angular.module('myApp', []); app.provider('providerPattern',function providerConstructor(){ //this function works as constructor function for provider this.firstName = 'Arnold '; this.lastName = ' Schwarzenegger' ; this.greetMessage = ' Welcome, This is default Greeting Message' ; //adding some method which we can call in app.config() function this.setGreetMsg = function(msg){ if(msg){ this.greetMessage = msg ; } }; //We can also add a method which can change firstName and lastName this.$get = function(){ var firstName = this.firstName; var lastName = this.lastName ; var greetMessage = this.greetMessage; var data={ greet: function(){ console.log('hello, ' + firstName + lastName+'! '+ greetMessage); } }; return data ; }; }); app.config( function(providerPatternProvider){ providerPatternProvider.setGreetMsg(' How do you do ?'); } );

작업 데모

요약:


팩토리 는 서비스 인스턴스를 반환하는 팩토리 함수를 사용합니다. 서비스 인스턴스 = fnFactory();

서비스 는 생성자 함수를 사용하고 Angular는 서비스 인스턴스를 생성하기 위해 'new' 키워드를 사용하여 이 생성자 함수를 호출합니다. serviceInstance = 새로운 fnServiceConstructor();

Provider 는 providerConstructor 함수를 정의하고 이 providerConstructor 함수는 $get 팩토리 함수를 정의합니다. Angular는 $get()을 호출하여 서비스 객체를 생성합니다. 공급자 구문에는 인스턴스화되기 전에 서비스 개체를 구성할 수 있는 추가 이점이 있습니다. 서비스 인스턴스 = $get();


Anant

여기 여러 사람들이 올바르게 지적한 것처럼 공장, 공급자, 서비스, 심지어 값과 상수도 같은 것의 버전입니다. provider 를 모두 해부할 수 있습니다. 이렇게:

여기에 이미지 설명 입력

이 이미지의 출처는 다음과 같습니다.

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


Luis Perez

공장

AngularJS에 기능을 제공하면 AngularJS는 팩토리가 요청될 때 반환 값을 캐시하고 주입합니다.

예시:

 app.factory('factory', function() { var name = ''; // Return value **is** the object that will be injected return { name: name; } })

용법:

 app.controller('ctrl', function($scope, factory) { $scope.name = factory.name; });

서비스

AngularJS에 함수를 제공하면 AngularJS는 new 를 호출하여 인스턴스화합니다. AngularJS가 생성하는 인스턴스는 서비스가 요청될 때 캐시되고 주입됩니다. new 가 서비스를 인스턴스화하는 데 사용되었으므로 this 키워드는 유효하고 인스턴스를 참조합니다.

예시:

 app.service('service', function() { var name = ''; this.setName = function(newName) { name = newName; } this.getName = function() { return name; } });

용법:

 app.controller('ctrl', function($scope, service) { $scope.name = service.getName(); });

공급자

AngularJS에 함수를 제공하면 AngularJS가 $get 함수를 호출합니다. 서비스가 요청될 때 캐시되고 주입될 $get 함수의 반환 값입니다.

공급자를 사용하면 AngularJS가 $get 메서드를 호출하여 주입 가능 항목을 가져 오기 전에 공급자를 구성할 수 있습니다.

예시:

 app.provider('provider', function() { var name = ''; this.setName = function(newName) { name = newName; } this.$get = function() { return { name: name } } })

사용법(컨트롤러에서 주입 가능)

 app.controller('ctrl', function($scope, provider) { $scope.name = provider.name; });

사용법(주사 가능한 것을 생성하기 위해 $get 이 호출되기 전에 공급자 구성)

 app.config(function(providerProvider) { providerProvider.setName('John'); });

pixelbits

공급자와 놀다가 흥미로운 점을 발견했습니다.

인젝터블의 가시성은 서비스 및 공장의 경우와 공급자의 경우 다릅니다. AngularJS "상수"(예: myApp.constant('a', 'Robert'); )를 선언하면 이를 서비스, 팩토리 및 공급자에 주입할 수 있습니다.

그러나 AngularJS "값"(예: myApp.value('b', {name: 'Jones'}); )을 선언하면 서비스와 팩토리에 주입할 수 있지만 공급자 생성 함수에는 주입할 수 없습니다. . 그러나 공급자에 대해 정의한 $get 함수에 삽입할 수 있습니다. 이것은 AngularJS 문서에 언급되어 있지만 놓치기 쉽습니다. 값 및 상수 메서드에 대한 섹션의 %provide 페이지에서 찾을 수 있습니다.

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>

justlooking

이것은 초보자에게 매우 혼란스러운 부분이며 쉬운 말로 설명하려고 노력했습니다.

AngularJS 서비스: 컨트롤러의 서비스 참조와 유틸리티 기능을 공유하는 데 사용됩니다. 서비스는 본질적으로 싱글톤이므로 하나의 서비스에 대해 브라우저에서 하나의 인스턴스만 생성되고 페이지 전체에서 동일한 참조가 사용됩니다.

서비스에서 이 개체를 사용하여 속성으로 함수 이름을 만듭니다.

AngularJS Factory: Factory 의 목적도 Service와 동일하지만 이 경우 새 객체를 생성하고 이 객체의 속성으로 기능을 추가하고 마지막에 이 객체를 반환합니다.

AngularJS Provider: 이것 의 목적은 다시 동일하지만 Provider는 $get 함수의 출력을 제공합니다.

Service, Factory 및 Provider를 정의하고 사용하는 방법은 http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider에 설명되어 있습니다.


Sheo Narayan

나에게 차이점을 이해하는 가장 좋고 간단한 방법은 다음과 같습니다.

 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 } }

가장 간단한 사고 방식은 다음과 같습니다.

  • 서비스는 싱글톤 개체 인스턴스입니다. 코드에 싱글톤 객체를 제공하려면 서비스를 사용하십시오.
  • 공장은 클래스입니다. 코드에 대한 사용자 정의 클래스를 제공하려면 팩토리를 사용하십시오(서비스는 이미 인스턴스화되어 있으므로 수행할 수 없음).

팩토리 '클래스' 예제는 주변의 주석과 제공자 차이에 제공됩니다.


Lukasz Frankowski

이 문제에 대한 나의 설명:

기본적으로 언급된 모든 유형(서비스, 공장, 공급자 등)은 구식 전역 변수와 마찬가지로 전역 변수(물론 전체 응용 프로그램에 대해 전역적임)를 만들고 구성하는 것입니다.

전역 변수는 권장되지 않지만 이러한 전역 변수의 실제 사용은 해당 컨트롤러에 변수를 전달하여 종속성 주입을 제공하는 것입니다.

"전역 변수"에 대한 값을 생성하는 데는 여러 수준의 복잡성이 있습니다.

  1. 일정한
    이것은 다른 언어의 상수와 마찬가지로 전체 애플리케이션 동안 수정되어서는 안 되는 실제 상수를 정의합니다(JavaScript에는 없는 것).


  2. 이것은 수정 가능한 값 또는 객체이며 다른 서비스나 팩토리를 생성할 때 삽입될 수도 있는 일부 전역 변수 역할을 합니다(자세한 내용 참조). 그러나 " 리터럴 값 "이어야 합니다. 즉, 실제 값을 작성해야 하며 계산 또는 프로그래밍 논리를 사용할 수 없습니다(즉, 39 또는 myText 또는 {prop: "value"} 는 괜찮지만 2 +2 는 아닙니다).
  3. 공장
    바로 계산할 수 있는 보다 일반적인 값입니다. 값을 계산하는 데 필요한 논리를 사용하여 AngularJS에 함수를 전달하면 AngularJS가 이를 실행하고 반환 값을 명명된 변수에 저장합니다.
    객체(이 경우 서비스 와 유사하게 작동함) 또는 함수(변수에 콜백 함수로 저장됨)를 반환할 수 있습니다.

  4. 서비스
    서비스는 값이 객체일 때만 유효하며 (생성자가 되는 것처럼) 함수에 직접 로직을 작성할 수 있을 뿐만 아니라 선언하고 액세스할 수 있는 팩토리 버전입니다 this 키워드를 사용하여 객체 속성.
  5. 공급자
    Factory 의 단순화된 버전인 서비스와 달리 공급자는 "전역" 변수를 초기화하는 더 복잡하지만 더 유연한 방법이며 가장 큰 유연성은 app.config에서 값을 설정하는 옵션입니다.
    app.config 에서 사용할 수 있는 this 키워드를 사용하여 선언된 속성이 있는 함수를 provider에 전달하여 serviceprovider 조합을 사용하는 것처럼 작동합니다.
    그런 다음 app.config 파일을 통해 위의 속성을 설정한 후 AngularJS에 의해 실행되는 별도의 $.get 함수가 필요하며 이 $.get 함수는 반환 값을 초기화하는 데 사용한다는 점에서 위 의 팩토리 처럼 동작합니다. "전역"변수.



yoel halb

내 이해는 아래에서 매우 간단합니다.

팩토리: 팩토리 내부에 객체를 생성하고 반환하기만 하면 됩니다.

서비스:

이 키워드를 사용하여 함수를 정의하는 표준 함수가 있습니다.

공급자:

$get 개체가 있으며 데이터를 반환하는 개체를 가져오는 데 사용할 수 있습니다.


sajan

Angular 문서 요약 :

  • 객체 생성 방법을 정의하는 다섯 가지 레시피 유형이 있습니다: Value , Factory , Service , ProviderConstant .
  • FactoryService 는 가장 일반적으로 사용되는 레시피입니다. 그들 사이의 유일한 차이점은 서비스 레시피는 사용자 정의 유형의 객체에 대해 더 잘 작동하는 반면 Factory 는 JavaScript 기본 및 기능을 생성할 수 있다는 것입니다.
  • 제공자 레시피는 핵심 레시피 유형이고 다른 모든 것들은 단지 그것에 대한 문법적 설탕입니다.
  • Provider 는 가장 복잡한 레시피 유형입니다. 전역 구성이 필요한 재사용 가능한 코드를 작성하지 않는 한 필요하지 않습니다.

여기에 이미지 설명 입력


SO의 베스트 답변:

https://stackoverflow.com/a/26924234/165673 (<-- GOOD) https://stackoverflow.com/a/27263882/165673
https://stackoverflow.com/a/16566144/165673


Yarin

모든 좋은 답변이 이미 있습니다. 나는 ServiceFactory 에 몇 가지 포인트를 더 추가하고 싶습니다. 서비스/공장의 차이와 함께. 그리고 다음과 같은 질문을 할 수도 있습니다.

  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.aServiceMethod()와 같이 함수를 호출 MyService

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

$http.get('/score').then(ScoreKeeper.setScore). 서버에서 점수를 가져와 점수를 초기화한 경우 약속 체인에서 ScoreKeeper.setScore 를 호출하고 싶을 수 있습니다. 이것에 문제가 있다는 것입니다 ScoreKeeper.setScore 호출 될 this 결합 null 당신이 오류를 얻을 수 있습니다. 더 좋은 방법은 $http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper)) 입니다. 서비스 메소드에서 이것을 사용하기로 선택하든 그렇지 않든, 호출 방법에 주의하십시오.

Service 에서 값 반환 :

JavaScript 생성자가 작동하는 방식으로 인해 constructor 함수에서 (ie, an Object) 을 반환하면 호출자는 이 인스턴스 대신 해당 개체를 가져옵니다.

이것은 기본적으로 아래에서 공장 예제를 복사하여 붙여넣고 factoryservice 교체할 수 있음을 의미합니다. 그러면 작동합니다.

 angular.service('MyService', function($http) { var api = {}; api.aServiceMethod= function() { return $http.get('/users'); }; return api; });

따라서 Angular가 new MyService()를 사용하여 서비스를 구성할 때 MyService 인스턴스 대신 해당 API 개체를 가져옵니다.

이것은 모든 복잡한 값(객체, 함수)에 대한 동작이지만 기본 유형에는 적용되지 않습니다.

공장:

팩토리는 값을 반환하는 평범한 오래된 함수입니다. 반환 값은 공장에 의존하는 것들에 주입되는 것입니다. Angular의 일반적인 팩토리 패턴은 다음과 같이 함수가 속성으로 포함된 객체를 반환하는 것입니다.

 angular.factory('MyFactory', function($http) { var api = {}; api.aFactoryMethod= function() { return $http.get('/users'); }; return api; });

팩토리 종속성에 대해 주입된 값은 팩토리의 반환 값이며 객체일 필요는 없습니다. 기능일 수 있습니다

위의 1 및 2 질문에 대한 답변:

대부분의 경우 모든 것에 팩토리를 사용하십시오. 그들의 행동은 더 이해하기 쉽습니다. 값을 반환할지 여부에 대해 선택의 여지가 없으며, 더군다나 잘못된 일을 했을 때 발생하는 버그도 없습니다.

그러나 종속성으로 주입하는 것에 대해 이야기할 때 여전히 "서비스"라고 합니다.

서비스/공장 동작은 매우 유사하며 어떤 사람들은 둘 중 하나가 괜찮다고 말할 것입니다. 그것은 다소 사실이지만 John Papa의 스타일 가이드의 조언을 따르고 공장을 고수하는 것이 더 쉽다는 것을 알았습니다.**


Ved

추가 설명은 팩토리는 함수/기본체를 생성할 수 있지만 서비스는 생성할 수 없다는 것입니다. Epokk의 http://jsfiddle.net/skeller88/PxdSP/1351/ 에 기반한 이 jsFiddle을 확인하십시오.

팩토리는 호출할 수 있는 함수를 반환합니다.

 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/


skeller88

이미 좋은 답변이 있지만 저는 이것을 공유하고 싶습니다.

우선: Provider 는 $injector(AngulaJS가 IoC 패턴에 대해 진행하는 방식)에 의해 주입된다고 가정 service (싱글톤 객체)를 생성하는 방법/레시피입니다.

그리고 가치, 공장, 서비스 및 상수 (4가지 방법) - 공급자 방법/수령자에 대한 구문 설탕.

Service vs Factory 부분이 있습니다: https://www.youtube.com/watch?v=BLzNCkPn3ao

서비스 는 실제로 우리가 알고 있는 4가지 작업을 수행하는 new 키워드에 관한 것입니다.

  1. 새로운 객체를 생성합니다
  2. prototype 객체에 연결합니다.
  3. this context 를 연결
  4. 그리고 this

그리고 Factory 는 Factory Pattern에 관한 것입니다 - 해당 서비스와 같은 객체를 반환하는 기능을 포함합니다.

  1. 다른 서비스를 사용할 수 있는 능력(종속성 있음)
  2. 서비스 초기화
  3. 지연/지연 초기화

그리고 이 간단하고 짧은 비디오: 제공자 도 다룹니다: https://www.youtube.com/watch?v=HvTZbQ_hUZY (공장에서 제공자로 이동하는 방법을 볼 수 있습니다.)

제공자 레시피는 앱이 완전히 시작/초기화되기 전에 주로 앱 구성에서 사용됩니다.


ses

이 모든 게시물을 읽은 후 그것은 나를 더 혼란스럽게 만들었습니다. 그러나 여전히 모든 것이 가치있는 정보입니다. 마침내 간단한 비교로 정보를 제공하는 다음 표를 찾았습니다.

  • 인젝터는 서비스와 특수 목적의 두 가지 유형의 객체를 생성하기 위해 레시피를 사용합니다.
  • 객체 생성 방법을 정의하는 다섯 가지 레시피 유형이 있습니다: Value, Factory, Service, Provider 및 Constant.
  • Factory와 Service는 가장 일반적으로 사용되는 레시피입니다. 그들 사이의 유일한 차이점은 서비스 레시피는 사용자 정의 유형의 객체에 대해 더 잘 작동하는 반면 Factory는 JavaScript 기본 및 기능을 생성할 수 있다는 것입니다.
  • 제공자 레시피는 핵심 레시피 유형이고 다른 모든 것들은 단지 그것에 대한 문법적 설탕입니다.
  • Provider는 가장 복잡한 레시피 유형입니다. 전역 구성이 필요한 재사용 가능한 코드를 작성하지 않는 한 필요하지 않습니다.
  • 컨트롤러를 제외한 모든 특수 목적 개체는 팩토리 레시피를 통해 정의됩니다.

여기에 이미지 설명 입력

그리고 초심자를 위해 이해하십시오:- 이것은 올바른 사용 사례가 아닐 수 있지만 높은 수준에서는 이것이 이 세 가지의 사용 사례입니다.

  1. Angular 모듈에서 사용하려면 config 함수를 provider로 생성해야 합니다.

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

  1. Ajax 호출 또는 타사 통합은 서비스 여야 합니다.
  2. 데이터 조작의 경우 팩토리로 생성

기본 시나리오의 경우 factory&Service는 동일하게 작동합니다.


BEJGAM SHIVA PRASAD

다음은 AngularjS의 개체 팩토리에 대한 코드 템플릿으로 생각해 낸 몇 가지 broilerplate 코드입니다. 설명하기 위해 Car/CarFactory를 예로 사용했습니다. 컨트롤러에서 간단한 구현 코드를 만듭니다.

 <script> angular.module('app', []) .factory('CarFactory', function() { /** * BroilerPlate Object Instance Factory Definition / Example */ this.Car = function() { // initialize instance properties angular.extend(this, { color : null, numberOfDoors : null, hasFancyRadio : null, hasLeatherSeats : null }); // generic setter (with optional default value) this.set = function(key, value, defaultValue, allowUndefined) { // by default, if (typeof allowUndefined === 'undefined') { // we don't allow setter to accept "undefined" as a value allowUndefined = false; } // if we do not allow undefined values, and.. if (!allowUndefined) { // if an undefined value was passed in if (value === undefined) { // and a default value was specified if (defaultValue !== undefined) { // use the specified default value value = defaultValue; } else { // otherwise use the class.prototype.defaults value value = this.defaults[key]; } // end if/else } // end if } // end if // update this[key] = value; // return reference to this object (fluent) return this; }; // end this.set() }; // end this.Car class definition // instance properties default values this.Car.prototype.defaults = { color: 'yellow', numberOfDoors: 2, hasLeatherSeats: null, hasFancyRadio: false }; // instance factory method / constructor this.Car.prototype.instance = function(params) { return new this.constructor() .set('color', params.color) .set('numberOfDoors', params.numberOfDoors) .set('hasFancyRadio', params.hasFancyRadio) .set('hasLeatherSeats', params.hasLeatherSeats) ; }; return new this.Car(); }) // end Factory Definition .controller('testCtrl', function($scope, CarFactory) { window.testCtrl = $scope; // first car, is red, uses class default for: // numberOfDoors, and hasLeatherSeats $scope.car1 = CarFactory .instance({ color: 'red' }) ; // second car, is blue, has 3 doors, // uses class default for hasLeatherSeats $scope.car2 = CarFactory .instance({ color: 'blue', numberOfDoors: 3 }) ; // third car, has 4 doors, uses class default for // color and hasLeatherSeats $scope.car3 = CarFactory .instance({ numberOfDoors: 4 }) ; // sets an undefined variable for 'hasFancyRadio', // explicitly defines "true" as default when value is undefined $scope.hasFancyRadio = undefined; $scope.car3.set('hasFancyRadio', $scope.hasFancyRadio, true); // fourth car, purple, 4 doors, // uses class default for hasLeatherSeats $scope.car4 = CarFactory .instance({ color: 'purple', numberOfDoors: 4 }); // and then explicitly sets hasLeatherSeats to undefined $scope.hasLeatherSeats = undefined; $scope.car4.set('hasLeatherSeats', $scope.hasLeatherSeats, undefined, true); // in console, type window.testCtrl to see the resulting objects }); </script>

다음은 더 간단한 예입니다. 위도와 경도를 노출하지만 다른 개체 속성을 통해 "위치" 개체를 예상하는 몇 가지 타사 라이브러리를 사용하고 있습니다. 나는 벤더 코드를 해킹하고 싶지 않았기 때문에 주변에 있는 "Position" 개체를 조정했습니다.

 angular.module('app') .factory('PositionFactory', function() { /** * BroilerPlate Object Instance Factory Definition / Example */ this.Position = function() { // initialize instance properties // (multiple properties to satisfy multiple external interface contracts) angular.extend(this, { lat : null, lon : null, latitude : null, longitude : null, coords: { latitude: null, longitude: null } }); this.setLatitude = function(latitude) { this.latitude = latitude; this.lat = latitude; this.coords.latitude = latitude; return this; }; this.setLongitude = function(longitude) { this.longitude = longitude; this.lon = longitude; this.coords.longitude = longitude; return this; }; }; // end class definition // instance factory method / constructor this.Position.prototype.instance = function(params) { return new this.constructor() .setLatitude(params.latitude) .setLongitude(params.longitude) ; }; return new this.Position(); }) // end Factory Definition .controller('testCtrl', function($scope, PositionFactory) { $scope.position1 = PositionFactory.instance({latitude: 39, longitude: 42.3123}); $scope.position2 = PositionFactory.instance({latitude: 39, longitude: 42.3333}); }) // end controller

;


James Earlywine

이 페이지와 문서 (내가 마지막으로 본 이후로 크게 개선된 것으로 보임)를 참조로 사용하여 5가지 유형의 제공자 중 4가지를 사용하는 다음 실제(-ish) 세계 데모를 만들었습니다. 가치, 상수, 공장 및 완전한 공급자.

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

작업 데모 .


net.uk.sweet

이 답변은 주제/질문을 다룹니다.

어떻게 Factory, Service 및 Constant — 공급자 레시피 위에 있는 구문 설탕입니까?

또는

공장, 서비스 및 공급자가 내부적으로 유사한 방식

기본적으로 일어나는 일은

factory() 를 만들 때 두 번째 인수에 제공된 function $get 하고 반환( provider(name, {$get:factoryFn }) ) provider 만 얻을 수 있지만 다른 속성/메서드는 없습니다. 해당 provider $get (이를 구성할 수 없음을 의미)

공장의 소스 코드

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

service() 만들 때 constructor 를 주입 function (서비스에서 제공한 생성자의 인스턴스를 반환)와 함께 factory()를 제공하고 반환합니다.

서비스 소스 코드

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

따라서 기본적으로 두 경우 모두 결국 제공한 함수로 $get 설정되는 제공자를 얻습니다.


A.B

나는 훌륭한 답변을 많이 알고 있지만 사용 경험을 공유해야합니다
1. 대부분의 불이행에 대한 service
2. 특정 인스턴스가 서비스를 생성하는 데 사용되는 factory

 // factory.js //////////////////////////// (function() { 'use strict'; angular .module('myApp.services') .factory('xFactory', xFactoryImp); xFactoryImp.$inject = ['$http']; function xFactoryImp($http) { var fac = function (params) { this._params = params; // used for query params }; fac.prototype.nextPage = function () { var url = "/_prc"; $http.get(url, {params: this._params}).success(function(data){ ... } return fac; } })(); // service.js ////////////////////////// (function() { 'use strict'; angular .module('myApp.services') .service('xService', xServiceImp); xServiceImp.$inject = ['$http']; function xServiceImp($http) { this._params = {'model': 'account','mode': 'list'}; this.nextPage = function () { var url = "/_prc"; $http.get(url, {params: this._params}).success(function(data){ ... } } })();

다음을 사용하여:

 controller: ['xFactory', 'xService', function(xFactory, xService){ // books = new instance of xFactory for query 'book' model var books = new xFactory({'model': 'book', 'mode': 'list'}); // accounts = new instance of xFactory for query 'accounts' model var accounts = new xFactory({'model': 'account', 'mode': 'list'}); // accounts2 = accounts variable var accounts2 = xService; ...

nguyên

파티에 조금 늦었습니다. 그러나 공장, 서비스 및 제공자 방법론을 사용하여 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-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; } ]);

Custom Services에 대한 "service" 방법론에 대한 코드(이것은 'factory'와 매우 유사하지만 구문 관점에서 다릅니다):

 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>


user203687

명확하게 하기 위해 AngularJS 소스에서 서비스가 팩토리 함수를 호출하는 것을 볼 수 있습니다. 이 함수는 다시 제공자 함수를 호출합니다.

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

Ricardo Rossi

간단한 방법으로 AngularJS에서 비즈니스 로직을 처리하는 세 가지 방법에 대해 논의해 보겠습니다. ( Yaakov의 Coursera AngularJS 과정에서 영감을 얻음 )

서비스 :

통사론:

앱.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. Singleton : 여러 모듈에 주입되면 모두 하나의 특정 인스턴스에만 액세스할 수 있습니다. 그렇기 때문에 서로 다른 컨트롤러 간에 데이터를 공유하는 것이 매우 편리합니다.

공장

먼저 구문을 살펴보겠습니다.

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() 메서드는 일반적으로 구성이 필요하지 않은 항목의 바로 가기로 사용됩니다.

공급자

먼저 구문을 다시 살펴보겠습니다.

 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. 동적으로 구성 가능한 팩토리를 생성할 수 있을 뿐만 아니라 팩토리를 사용할 때 provider 메소드를 사용하여 전체 애플리케이션의 부트스트랩에서 팩토리를 한 번만 사용자 정의할 수 있습니다.
  3. 그런 다음 공장은 사용자 지정 설정으로 응용 프로그램 전체에서 사용할 수 있습니다. 즉, 애플리케이션이 시작되기 전에 이 팩토리를 구성할 수 있습니다. .service 또는 .factory 메소드로 서비스를 구성할 때 배후에서 실제로 실행되는 것이라고 언급되어 있습니다.
  4. $get 은 공급자 인스턴스에 직접 연결된 함수입니다. 그 기능은 공장 기능입니다. .factory 메소드 에 제공 하기 위해 사용하는 것과 같습니다. 그 기능에서 우리는 우리 자신의 서비스를 만듭니다. 함수인 이 $get 속성은 공급자를 공급자로 만듭니다. AngularJS는 공급자가 값이 Angular가 팩토리 함수로 취급할 함수인 $get 속성을 가질 것으로 예상합니다. 그러나 이 전체 공급자 설정을 매우 특별하게 만드는 것은 config 개체를 제공할 수 있고 일반적으로 나중에 전체 응용 프로그램을 구성할 수 있는 단계에서 덮어쓸 수 있는 기본값이 함께 제공된다는 사실입니다.

Pritam Banerjee

공장: 공장 내부에서 실제로 객체를 생성하고 반환하는 공장입니다.
service: this 키워드를 사용하여 기능을 정의하는 표준 기능이 있는 서비스입니다.
provider: $get 정의한 공급자가 있으며 데이터를 반환하는 개체를 가져오는 데 사용할 수 있습니다.


Mohanrajan

기본적으로 공급자, 공장 및 서비스는 모두 서비스입니다. Factory는 필요한 모든 것이 $get() 함수일 때 서비스의 특별한 경우이므로 더 적은 코드로 작성할 수 있습니다.

서비스, 공장 및 공급자 간의 주요 차이점은 복잡성입니다. 서비스는 가장 단순한 형태이고 팩토리는 좀 더 강력하며 공급자는 런타임에 구성할 수 있습니다.

다음은 각각을 언제 사용해야 하는지에 대한 요약입니다.

공장 : 제공하는 값은 다른 데이터를 기반으로 계산해야 합니다.

서비스 : 메서드가 있는 개체를 반환하고 있습니다.

제공자 : 구성 단계에서 생성되기 전에 생성될 객체를 구성할 수 있기를 원합니다. 앱이 완전히 초기화되기 전에 주로 앱 구성에서 공급자를 사용합니다.


eGhoul

1. 서비스는 필요할 때 생성되고 애플리케이션 수명 주기가 끝날 때까지(브라우저가 닫힐 때까지) 정리되지 않는 단일 개체입니다. 컨트롤러는 더 이상 필요하지 않을 때 파괴되고 정리됩니다.

2. 서비스를 생성하는 가장 쉬운 방법은 factory() 메서드를 사용하는 것입니다. factory() 메서드를 사용하면 서비스 기능과 서비스 데이터를 포함하는 객체를 반환하여 서비스를 정의할 수 있습니다. 서비스 정의 기능은 $http 및 $q와 같은 주입 가능한 서비스를 배치하는 곳입니다. 전:

 angular.module('myApp.services') .factory('User', function($http) { // injectables go here var backendUrl = "http://localhost:3000"; var service = { // our factory definition user: {}, setName: function(newName) { service.user['name'] = newName; }, setEmail: function(newEmail) { service.user['email'] = newEmail; }, save: function() { return $http.post(backendUrl + '/users', { user: service.user }); } }; return service; });

앱에서 factory() 사용

런타임에 필요한 곳에 간단히 주입할 수 있으므로 애플리케이션에서 팩토리를 사용하기 쉽습니다.

 angular.module('myApp') .controller('MainController', function($scope, User) { $scope.saveUser = User.save; });
  1. 반면에 service() 메서드를 사용하면 생성자 함수를 정의하여 서비스를 생성할 수 있습니다. 원시 자바스크립트 객체 대신 프로토타입 객체를 사용하여 서비스를 정의할 수 있습니다. factory() 메소드와 유사하게, 우리는 또한 함수 정의에서 인젝터블을 설정할 것입니다.
  2. 서비스를 생성하는 가장 낮은 수준의 방법은 제공() 메서드를 사용하는 것입니다. 이것은 .config() 함수를 사용하여 구성할 수 있는 서비스를 만드는 유일한 방법입니다. 이전 to 메소드와 달리 정의된 this.$get() 함수 정의에서 주입 가능 항목을 설정합니다.

Shankar Gangadhar

구문 설탕은 차이점 입니다. 제공자만 필요합니다. 즉, 공급자만 실제 각도이고 다른 모든 것은 파생됩니다(코드를 줄이기 위해). 값만 반환하고 계산이나 함수는 반환하지 않는 Value()라는 간단한 버전도 있습니다. 짝수 값은 공급자에서 파생됩니다!

그렇다면 왜 그러한 합병증이 발생합니까? 왜 우리는 공급자를 사용하고 다른 모든 것을 잊어 버릴 수 없습니까? 코드를 쉽게 작성하고 더 나은 의사 소통을 할 수 있도록 도와줍니다. 비꼬는 대답은 복잡할수록 더 잘 팔리는 프레임워크가 될 것입니다.


  • 값을 반환할 수 있는 공급자 = Value
  • 인스턴스화하고 반환할 수 있는 공급자 = Factory(+ Value)
  • 인스턴스화할 수 있는 제공자 + 무언가를 할 수 있는 제공자 = 서비스(+ 공장, + 가치)
  • 공급자 = $get(+Factory, + Service, + Value)이라는 속성을 포함해야 합니다.

각도 주입은 이러한 결론에 도달하는 첫 번째 힌트를 제공합니다.

"$injector는 서비스가 아니라 팩토리가 아니라 공급자가 " 제공자가 정의한 대로 개체 인스턴스를 검색하는 데 사용됩니다.

그리고 더 나은 대답은 다음과 같습니다. "Angular 서비스는 서비스 팩토리에 의해 생성됩니다. 이러한 서비스 팩토리는 차례로 서비스 공급자에 의해 생성되는 함수입니다. 서비스 공급자는 생성자 함수입니다. 인스턴스화될 때 속성을 포함해야 합니다. 서비스 팩토리 기능을 보유하는 $get이라고 합니다."

따라서 마스터 공급자와 인젝터 및 모든 것이 제자리에 들어갈 것입니다. :) . 그리고 $get이 IServiceProvider로부터 상속받아 프로바이더에서 구현될 수 있을 때 Typescript에서 흥미로워집니다.


Blue Clouds

출처 : http:www.stackoverflow.com/questions/15666048/angularjs-service-vs-provider-vs-factory

반응형