AngularJS: सेवा बनाम प्रदाता बनाम कारखाना


3319

एक में क्या अंतर है Service, Providerऔर FactoryAngularJS में?


244
मैंने पाया कि सभी कोणीय शब्द शुरुआती लोगों के लिए डराने वाले थे। हमने इस चीटशीट के साथ शुरुआत की, जो हमारे प्रोग्रामर्स को Angular demisx.github.io/angularjs/2014/09/14/… सीखने के दौरान समझने में थोड़ी आसान थी । आशा है कि इससे आपकी टीम को भी मदद मिलेगी।
17

7
मेरी राय में, अंतर को समझने का सबसे अच्छा तरीका एंगुलर के स्वयं के प्रलेखन का उपयोग कर रहा है: docs.angularjs.org/guide/providers यह बहुत अच्छी तरह से समझाया गया है और आपको इसे समझने में मदद करने के लिए एक अजीब उदाहरण का उपयोग करता है।
राफेल मर्लिन

3
@Blaise धन्यवाद! पोस्ट में मेरी टिप्पणी के अनुसार, मैंने इसे जानबूझकर छोड़ दिया, क्योंकि मेरे अनुभव से 99% उपयोग के मामलों को सफलतापूर्वक नियंत्रित किया जा सकता है service.factory। आगे इस विषय को जटिल नहीं करना चाहता था।
डेनिक्स

3
मुझे यह चर्चा भी बहुत उपयोगी stackoverflow.com/questions/18939709/…
आनंद गुप्ता

3
यहाँ कैसेservices,factoriesऔरprovidersकाम करता है के बारे में कुछ अच्छे जवाब हैं।
मिस्टालिस

जवाबों:


2866

AngularJS मेलिंग सूची से मुझे एक अद्भुत धागा मिला जो सेवा बनाम कारखाने बनाम प्रदाता और उनके इंजेक्शन के उपयोग के बारे में बताता है। जवाब संकलन:

सेवाएं

सिंटैक्स: module.service( 'serviceName', function );
परिणाम: सेवानाम को एक इंजेक्शन योग्य तर्क के रूप में घोषित करते समय आपको फ़ंक्शन के एक उदाहरण के साथ प्रदान किया जाएगा। दूसरे शब्दों में new FunctionYouPassedToService()

कारखाना

सिंटेक्स: module.factory( 'factoryName', function );
परिणाम: जब कारखानेनाम को एक इंजेक्टेबल तर्क के रूप में घोषित किया जाता है, तो आपको उस मान के साथ प्रदान किया जाएगा जो मॉड्यूल.फैक्टिंग को पारित फ़ंक्शन संदर्भ को लागू करके वापस किया जाता है

प्रदाताओं

सिंटैक्स: module.provider( 'providerName', function );
परिणाम: जब प्रदाता को एक इंजेक्शन योग्य तर्क के रूप में घोषित किया जाता है तो आपको प्रदान किया जाएगा (new ProviderFunction()).$get() । $ पाने के तरीके को कहा जाता है - इससे पहले कंस्ट्रक्टर फ़ंक्शन ProviderFunctionको त्वरित किया जाता है - मॉड्यूल।प्रोवाइडर को दिया जाने वाला फ़ंक्शन संदर्भ है।

प्रदाताओं को यह फायदा है कि उन्हें मॉड्यूल कॉन्फ़िगरेशन चरण के दौरान कॉन्फ़िगर किया जा सकता है।

दिए गए कोड के लिए यहां देखें ।

यहाँ मिसको द्वारा एक और शानदार व्याख्या दी गई है:

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एक फ़ंक्शन है जो मूल्य बनाने के लिए जिम्मेदार है। ध्यान दें कि फ़ैक्टरी फ़ंक्शन अन्य निर्भरताओं के लिए पूछ सकता है।

लेकिन क्या होगा यदि आप अधिक ओओ बनना चाहते हैं और ग्रीटियर नामक एक वर्ग है?

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, factory, और valueसब प्रदाता से प्राप्त कर रहे हैं।

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

58
यह भी देखें stackoverflow.com/a/13763886/215945 जो सेवा और कारखाने के बीच के अंतरों पर चर्चा करता है।
मार्क राजकोक

3
611 संपादित करने में मैंने कोणीय स्थिरांक और मूल्यों का उपयोग जोड़ा। दूसरे के पहले से दिखाए गए मतभेदों को प्रदर्शित करने के लिए। jsbin.com/ohamub/611/edit
निक

17
यद्यपि फ़ंक्शन की आवृत्ति बनाकर किसी सेवा को कॉल किया जाता है। यह वास्तव में केवल एक बार प्रति इंजेक्टर बनाया जाता है जो इसे सिंगलटन की तरह बनाता है। docs.angularjs.org/guide/dev_guide.services.creating_services
एंजलोक

33
यदि यह स्पष्ट व्यावहारिक उदाहरण का उपयोग करता है तो यह उदाहरण अविश्वसनीय हो सकता है। मैं की तरह क्या बातें की बात पता लगाने की कोशिश खो जाना toEqualऔर greeter.Greetहै। क्यों नहीं कुछ और अधिक वास्तविक और भरोसेमंद का उपयोग करें?
काइल पेनेल

5
फ़ंक्शन अपेक्षा का उपयोग करना () कुछ समझाने के लिए एक खराब विकल्प है। अगली बार वास्तविक विश्व कोड का उपयोग करें।
क्रेग

812

जेएस फिडेल डेमो

"नमस्ते दुनिया" 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() {

    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>


2
फ़ंक्शन thisमें संदर्भ नहीं बदलता है $get? - अब आप उस फ़ंक्शन में तत्काल प्रदाता को संदर्भित नहीं करते हैं।
नैट-विल्किंस

12
@ नैट: thisसंदर्भ को नहीं बदलता है, वास्तव में, क्योंकि जिसे बुलाया जा रहा है new Provider()। $ get (), जहां Providerफ़ंक्शन को पारित किया जा रहा है app.provider। यह कहना है कि $get()निर्माण पर एक विधि के रूप में कहा जा रहा है Provider, इसलिए उदाहरण के रूप में thisसंदर्भित करेगा Provider
ब्रेंडन

1
@Brandon ओह ठीक है कि तब थोड़े साफ है। पहली नज़र में भ्रामक - स्पष्टीकरण के लिए धन्यवाद!
नैट-विल्किंस

3
Unknown provider: helloWorldProvider <- helloWorldइसे स्थानीय स्तर पर चलाने पर मुझे क्यों मिलता है ? यह टिप्पणी करते हुए, अन्य 2 उदाहरणों के लिए एक ही त्रुटि। क्या कुछ छिपी प्रदाता कॉन्फ़िगरेशन है? (कोणीय 1.0.8) - पाया गया: stackoverflow.com/questions/12339272/…
एंटोनी

4
क्या कारण है कि @Antoine को "अज्ञात प्रदान: helloWorldProvider" त्रुटि मिलती है क्योंकि आपके .config कोड में, आप 'helloWorldProvider' का उपयोग करते हैं, लेकिन जब आप प्रदाता को myApp.proproider ('helloWorld', फ़ंक्शन) () में परिभाषित करते हैं, तो आप उपयोग करते हैं। 'नमस्ते दुनिया'? दूसरे शब्दों में, आपके कॉन्फिगर कोड में, कोणीय को कैसे पता चलता है कि आप helloWorld प्रदाता का उल्लेख कर रहे हैं? धन्यवाद
jmtoung

645

TL; DR

1) जब आप किसी फैक्ट्री का उपयोग कर रहे होते हैं तो आप एक ऑब्जेक्ट बनाते हैं, उसमें गुण जोड़ते हैं, फिर उसी ऑब्जेक्ट को वापस करते हैं। जब आप इस कारखाने को अपने नियंत्रक में पास करते हैं, तो ऑब्जेक्ट पर मौजूद गुण अब आपके कारखाने के माध्यम से उस नियंत्रक में उपलब्ध होंगे।

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) जब आप सेवा का उपयोग कर रहे होते हैं , तो AngularJS इसे 'नए' कीवर्ड के साथ पर्दे के पीछे कर देता है। उसके कारण, आप 'इस' में गुण जोड़ेंगे और सेवा 'यह' वापस आ जाएगी। जब आप सेवा को अपने नियंत्रक में पास करते हैं, तो 'यह' पर वे गुण अब आपकी सेवा के माध्यम से उस नियंत्रक पर उपलब्ध होंगे।

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



गैर टीएल, डॉ

1) फैक्ट्री
फैक्ट्री किसी सेवा को बनाने और कॉन्फ़िगर करने का सबसे लोकप्रिय तरीका है। वास्तव में टीएल से बहुत अधिक नहीं है; डीआर ने कहा। आप बस एक ऑब्जेक्ट बनाते हैं, उसमें गुण जोड़ते हैं, फिर उसी ऑब्जेक्ट को वापस करते हैं। फिर जब आप कारखाने को अपने नियंत्रक में पास करते हैं, तो ऑब्जेक्ट पर मौजूद गुण अब आपके कारखाने के माध्यम से उस नियंत्रक में उपलब्ध होंगे। एक अधिक व्यापक उदाहरण नीचे है।

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

अब हम जो भी गुण us सेवा ’से जोड़ते हैं, वह हमारे लिए तब उपलब्ध होगा जब हम 'myFactory’ को अपने नियंत्रक में पास करेंगे।

अब हमारे कॉलबैक फ़ंक्शन में कुछ 'निजी' चर जोड़ते हैं। ये कंट्रोलर से सीधे नहीं मिलेंगे, लेकिन हम अंततः 'सर्विस' पर कुछ गेटटर / सेटर के तरीकों को सेट कर देंगे, ताकि जरूरत पड़ने पर इन 'प्राइवेट' वेरिएबल को बदल सकें।

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

यहाँ आप देखेंगे कि हम उन चर / फ़ंक्शन को 'सेवा' में संलग्न नहीं कर रहे हैं। हम उन्हें केवल उपयोग करने या बाद में संशोधित करने के लिए बना रहे हैं।

  • बेस यूआरएल वह आधार URL है जो आईट्यून्स एपीआई की आवश्यकता होती है
  • _artist वह कलाकार है जिसे हम देखना चाहते हैं
  • _finalUrl अंतिम और पूरी तरह से निर्मित URL है, जिसे हम आईट्यून्स पर कॉल करेंगे
  • MakeUrl एक ऐसा फंक्शन है जो हमारे आईट्यून्स फ्रेंडली URL को बनाएगा और लौटाएगा।

अब जबकि हमारे सहायक / निजी चर और कार्य स्थान पर हैं, तो आइए कुछ गुणों को 'सेवा' ऑब्जेक्ट में जोड़ें। जो कुछ भी हम 'सेवा' पर डालते हैं, जिसका उपयोग सीधे 'नियंत्रक' में से किया जा सकता है।

हम सेटआर्टिस्ट और गेटआर्टिस्ट मेथड बनाने जा रहे हैं जो बस कलाकार को लौटाते हैं या सेट करते हैं। हम एक ऐसी विधि भी बनाने जा रहे हैं जो हमारे बनाए गए URL के साथ iTunes API को कॉल करेगी। यह विधि एक वादा वापस करने जा रही है जो आइट्यून्स एपीआई से डेटा वापस आने के बाद पूरा होगा। यदि आपको AngularJS में वादों का उपयोग करने का अधिक अनुभव नहीं है, तो मैं उन पर एक गहरा गोता लगाने की सलाह देता हूं।

नीचे setArtist आप कलाकार स्थापित करने के लिए एक कलाकार स्वीकार करता है और अनुमति देता है। getArtist कलाकार को लौटाता है। callItunes पहले URL बनाता है () हम अपने $ http अनुरोध के साथ उपयोग करेंगे URL बनाने के लिए। फिर यह एक वादा वस्तु सेट करता है, हमारे अंतिम url के साथ $ http अनुरोध करता है, फिर क्योंकि $ http एक वादा वापस करता है, हम हमारे अनुरोध के बाद .suor या .error को कॉल करने में सक्षम हैं। फिर हम आईट्यून्स डेटा के साथ अपने वादे को हल करते हैं, या हम इसे एक संदेश के साथ अस्वीकार करते हुए कहते हैं कि 'एक त्रुटि थी'।

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' के डेटा के साथ हमारी $ स्कोप ऑब्जेक्ट पर गुण सेट किए। ऊपर केवल ट्रिकी कोड है यदि आपने पहले कभी वादों को निपटाया नहीं है। क्योंकि callItunes एक वादा वापस कर रहा है, हम .then () विधि का उपयोग करने में सक्षम हैं और केवल एक बार हमारा स्कोप iTunes डेटा के साथ पूरा होने पर $ गुंजाइश.data.artistData सेट करते हैं। आप देखेंगे कि हमारा नियंत्रक बहुत 'पतला' है (यह एक अच्छा कोडिंग अभ्यास है)। हमारे सभी तर्क और निरंतर डेटा हमारी सेवा में स्थित हैं, हमारे नियंत्रक में नहीं।

2) सेवा
किसी सेवा को बनाते समय यह जानना सबसे बड़ी बात है कि यह 'नए' कीवर्ड के साथ त्वरित है। आपके लिए जावास्क्रिप्ट गुरु यह आपको कोड की प्रकृति में एक बड़ा संकेत देना चाहिए। आपके लिए जावास्क्रिप्ट में एक सीमित पृष्ठभूमि के साथ या उन लोगों के लिए जो वास्तव में 'नया' कीवर्ड से परिचित नहीं हैं, आइए कुछ जावास्क्रिप्ट बुनियादी बातों की समीक्षा करें जो अंततः एक सेवा की प्रकृति को समझने में हमारी मदद करेंगे।

जब आप किसी फ़ंक्शन को 'नए' कीवर्ड से जोड़ते हैं, तो वास्तव में एक फ़ंक्शन बनाते हैं और 'नए' कीवर्ड के साथ इसे लागू करते हैं, तो चलिए देखते हैं कि इंटरप्रेटर क्या करता है जब वह 'नया' कीवर्ड देखता है। अंतिम परिणाम दोनों समान होंगे।

पहले हम अपना कंस्ट्रक्टर बनाएं।

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

यह एक विशिष्ट जावास्क्रिप्ट कंस्ट्रक्टर फ़ंक्शन है। अब जब भी हम 'नया' कीवर्ड का उपयोग करके व्यक्ति फ़ंक्शन को आमंत्रित करते हैं, तो 'यह' नए बनाए गए ऑब्जेक्ट के लिए बाध्य होगा।

अब हम अपने व्यक्ति के प्रोटोटाइप पर एक विधि जोड़ते हैं ताकि यह हमारे व्यक्ति 'वर्ग' के हर उदाहरण पर उपलब्ध होगा।

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

अब, क्योंकि हम प्रोटोटाइप पर SayName फ़ंक्शन डालते हैं, इसलिए पर्सन का हर इंस्टेंस, उस नाम के नाम से क्रम अलर्ट में SayName फ़ंक्शन को कॉल करने में सक्षम होगा।

अब जब हमारे पास हमारा व्यक्ति निर्माण कार्य है और इसके प्रोटोटाइप पर हमारा नामनाम कार्य है, तो वास्तव में व्यक्ति का एक उदाहरण बनाएं और फिर नामनाम फ़ंक्शन को कॉल करें।

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

तो सभी एक साथ एक व्यक्ति निर्माणकर्ता बनाने के लिए कोड, एक फ़ंक्शन को इसे प्रोटोटाइप में जोड़कर, एक व्यक्तिगत उदाहरण बना रहा है, और फिर फ़ंक्शन को इसके प्रोटोटाइप पर कॉल करना इस तरह दिखता है।

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’

अब देखते हैं कि जब आप जावास्क्रिप्ट में 'नए' कीवर्ड का उपयोग करते हैं तो वास्तव में क्या हो रहा है। पहली बात जो आपको ध्यान देनी चाहिए वह यह है कि हमारे उदाहरण में 'नया' का उपयोग करने के बाद, हम 'टायलर' पर एक विधि (SayName) को कॉल करने में सक्षम हैं जैसे कि यह एक वस्तु थी - ऐसा इसलिए है क्योंकि यह है। तो सबसे पहले, हम जानते हैं कि हमारा व्यक्ति निर्माता एक ऑब्जेक्ट लौटा रहा है, चाहे हम कोड में देख सकते हैं या नहीं। दूसरा, हम जानते हैं कि क्योंकि हमारा फ़ंक्शन नाम प्रोटोटाइप पर स्थित है, न कि सीधे व्यक्ति के उदाहरण पर, वह वस्तु जो व्यक्ति फ़ंक्शन वापस कर रहा है, उसे विफल लुकअप पर अपने प्रोटोटाइप में प्रतिनिधि होना चाहिए। अधिक सरल शब्दों में, जब हम tyler.sayName कहते हैं () दुभाषिया कहता है, "ठीक है, मैं 'tyler' ऑब्जेक्ट को देखने जा रहा हूं जिसे हमने अभी बनाया है, SayName फ़ंक्शन का पता लगाएं, फिर कॉल करें। एक मिनट रुकिए, मैं इसे यहाँ नहीं देखता - मैं देख रहा हूँ कि मेरा नाम और उम्र है, मुझे प्रोटोटाइप की जाँच करने दें। हाँ, ऐसा लगता है कि यह प्रोटोटाइप पर है, मुझे इसे कॉल करने दें। ”

नीचे इस बात के लिए कोड है कि आप कैसे सोच सकते हैं कि 'नया' कीवर्ड वास्तव में जावास्क्रिप्ट में क्या कर रहा है। यह मूल रूप से उपरोक्त पैराग्राफ का एक कोड उदाहरण है। मैंने 'इंटरप्रेटर व्यू' डाला है या जिस तरह से इंटरप्रेटर ने नोटों के अंदर कोड देखा है।

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

अब 'नया' कीवर्ड वास्तव में जावास्क्रिप्ट में क्या करता है, इसका ज्ञान होने के बाद, AngularJS में एक सेवा का निर्माण करना आसान होना चाहिए।

सेवा बनाते समय समझने वाली सबसे बड़ी बात यह है कि सेवाओं को 'नए' कीवर्ड के साथ त्वरित किया जाता है। उस ज्ञान को ऊपर दिए गए हमारे उदाहरणों के साथ जोड़ते हुए, अब आपको यह पहचानना चाहिए कि आप अपने गुणों और विधियों को सीधे 'इस' से जोड़ देंगे, जिसे बाद में सेवा से वापस कर दिया जाएगा। आइए इस पर एक नज़र डालें।

मूल रूप से हमने फ़ैक्टरी उदाहरण के साथ जो किया था, उसके विपरीत, हमें एक ऑब्जेक्ट बनाने की ज़रूरत नहीं है, फिर उस ऑब्जेक्ट को वापस लौटाएं, क्योंकि पहले कई बार उल्लेख किया गया था, हमने 'नए' कीवर्ड का उपयोग किया था, इसलिए दुभाषिया उस ऑब्जेक्ट का निर्माण करेगा, क्या इसे प्रतिनिधि के पास भेजना है यह प्रोटोटाइप है, तो काम किए बिना हमारे लिए इसे वापस कर दें।

पहले चीजें पहले, चलो हमारे 'निजी' और सहायक समारोह बनाएँ। यह बहुत परिचित लगना चाहिए क्योंकि हमने अपने कारखाने के साथ सटीक काम किया है। मैं यह नहीं बताऊंगा कि प्रत्येक पंक्ति यहाँ क्या करती है क्योंकि मैंने कारखाने के उदाहरण में, यदि आप भ्रमित हैं, तो कारखाने के उदाहरण को फिर से पढ़ें।

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

अब, हम अपने सभी तरीकों को संलग्न करेंगे जो हमारे नियंत्रक में 'इस' के लिए उपलब्ध होंगे।

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

});

अब हमारे कारखाने की तरह, सेटआर्टिस्ट, गेटआर्टिस्ट, और कॉल इट्यून्स उपलब्ध होंगे जो भी नियंत्रक हम 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);
      })
  }
});

जैसा कि मैंने पहले उल्लेख किया है, एक बार जब आप वास्तव में समझते हैं कि 'नया' क्या करता है, तो सेवाएं लगभग AngularJS में कारखानों के समान हैं।

3) प्रदाता

प्रोवाइडर्स के बारे में याद रखने वाली सबसे बड़ी बात यह है कि वे एकमात्र ऐसी सेवा हैं, जिसे आप अपने एप्लिकेशन के ऐप में बदल सकते हैं। यदि आपके एप्लिकेशन में हर जगह उपलब्ध होने से पहले आपको अपनी सेवा वस्तु के कुछ हिस्से को बदलने की आवश्यकता हो तो यह बहुत महत्वपूर्ण है। हालाँकि बहुत कुछ सेवाओं / कारखानों के समान है, लेकिन कुछ अंतर हैं जिनकी हम चर्चा करेंगे।

पहले हमने अपने प्रदाता को उसी तरह स्थापित किया जैसे हमने अपनी सेवा और कारखाने के साथ किया था। नीचे दिए गए चर हमारे 'निजी' और सहायक समारोह हैं।

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

* फिर से अगर उपरोक्त कोड का कोई भी भाग भ्रमित हो रहा है, तो फैक्टरी अनुभाग देखें, जहां मैं समझाता हूं कि यह सब अधिक विवरण क्या करता है।

आप तीन खंडों के रूप में प्रदाताओं के बारे में सोच सकते हैं। पहला खंड 'निजी' चर / कार्य हैं जिन्हें बाद में संशोधित / सेट किया जाएगा (ऊपर दिखाया गया है)। दूसरा खंड वे चर / कार्य हैं जो आपके app.config फ़ंक्शन में उपलब्ध होंगे और इसलिए वे कहीं और उपलब्ध होने से पहले बदलने के लिए उपलब्ध हैं (ऊपर दिखाए गए हैं)। यह ध्यान रखना महत्वपूर्ण है कि उन चर को 'इस' कीवर्ड से जोड़ना होगा। हमारे उदाहरण में, केवल 'thingFromConfig' app.config में परिवर्तन करने के लिए उपलब्ध होगा। तीसरा खंड (नीचे दिखाया गया है) सभी चर / कार्य हैं जो आपके नियंत्रक में उपलब्ध होंगे जब आप उस विशिष्ट नियंत्रक में 'myProvider' सेवा में पास होंगे।

प्रदाता के साथ एक सेवा बनाते समय, केवल गुण / विधियाँ जो आपके नियंत्रक में उपलब्ध होंगी, वे गुण / विधियाँ हैं जिन्हें $ 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
    }
  }
});

अब हमारे कारखाने और सेवा की तरह, सेटआर्टिस्ट, गेटआर्टिस्ट और कॉल इट्यून्स उपलब्ध होंगे जो भी हमारे नियंत्रक से गुजरता है, जिसमें मैं 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;
});

जैसा कि पहले उल्लेख किया गया है, प्रदाता के साथ एक सेवा बनाने का पूरा बिंदु एप्लिकेशन के माध्यम से कुछ चर को बदलने में सक्षम होना है। अंतिम वस्तु को आवेदन से पहले पारित करने से पहले। चलिए इसका एक उदाहरण देखते हैं।

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 में दिखाई देगा, तो यह 'यह वाक्य सेट किया गया ...' होगा।


11
इस उत्कृष्ट लेखन में जो एकमात्र हिस्सा गायब है वह किसी कारखाने में सेवा का उपयोग करने के सापेक्ष फायदे हैं; जो स्पष्ट रूप से लायर द्वारा स्वीकार किए गए उत्तर में स्पष्ट किया गया है
अनंत

2
FWIW (शायद ज्यादा नहीं), यहाँ एक ब्लॉगर कि कोणीय के साथ इस मुद्दे पर ले जाता है, और इस तरह providerProvider नहीं है codeofrob.com/entries/you-have-ruined-javascript.html
barlop

3
'जावास्क्रिप्ट गुरु' पंचलाइन धूर्त थी। : मुझे लगता है कि यह उत्तर चीजों को बहुत साफ करता है। बहुत बढ़िया लिखा है।
अमरमिश्र

4
आपके TLDR को TLDR की आवश्यकता है।
जेन्सबी

3
@JensB tl; डॉ - जानें रिएक्ट।
टायलर मैकगिनिस

512

सभी सेवाएँ एकल हैं ; वे ऐप के अनुसार एक बार तुरंत मिल जाते हैं। वे किसी भी प्रकार के हो सकते हैं , चाहे वह एक आदिम, वस्तु शाब्दिक, कार्य हो, या एक कस्टम प्रकार का उदाहरण भी हो।

value, factory, service, constant, और providerतरीकों सभी प्रदाताओं रहे हैं। वे इंजेक्टर सिखाते हैं कि सेवाओं को कैसे त्वरित किया जाए।

सबसे क्रिया, लेकिन यह भी सबसे व्यापक एक प्रदाता नुस्खा है। शेष चार नुस्खा प्रकार - मूल्य, फैक्टरी, सेवा और लगातार - एक प्रदाता नुस्खा के शीर्ष पर सिर्फ वाक्यात्मक चीनी हैं

  • मूल्य पकाने की विधि सबसे सामान्य स्थिति है, जहां आप अपने आप को सेवा का दृष्टांत और प्रदान करना है instantiated मूल्य इंजेक्टर करने के लिए।
  • फैक्टरी नुस्खा इंजेक्टर एक कारखाने समारोह है कि यह कॉल जब यह सेवा का दृष्टांत की जरूरत है देता है। जब कहा जाता है, फ़ैक्टरी फ़ंक्शन सेवा आवृत्ति बनाता है और वापस करता है। सेवा की निर्भरता को फ़ंक्शन के तर्कों के रूप में इंजेक्ट किया जाता है। तो इस नुस्खे का उपयोग करने से निम्नलिखित क्षमताएं जुड़ जाती हैं:
    • अन्य सेवाओं का उपयोग करने की क्षमता (निर्भरता है)
    • सेवा आरंभ
    • विलंबित / आलसी आरंभीकरण
  • सेवा नुस्खा लगभग फैक्टरी नुस्खा के रूप में ही है, लेकिन यहाँ इंजेक्टर एक invokes निर्माता के बजाय नए ऑपरेटर एक कारखाने समारोह के साथ।
  • प्रदाता नुस्खा आमतौर पर है overkill । यह आपको कारखाने के निर्माण को कॉन्फ़िगर करने की अनुमति देकर अप्रत्यक्ष की एक और परत जोड़ता है।

    आपको प्रदाता नुस्खा का उपयोग केवल तभी करना चाहिए जब आप एप्लिकेशन-वाइड कॉन्फ़िगरेशन के लिए एक एपीआई को उजागर करना चाहते हैं जो कि आवेदन शुरू होने से पहले किया जाना चाहिए। यह आमतौर पर केवल पुन: प्रयोज्य सेवाओं के लिए दिलचस्प है जिनके व्यवहार को अनुप्रयोगों के बीच थोड़ा भिन्न होने की आवश्यकता हो सकती है।

  • लगातार नुस्खा सिर्फ मूल्य नुस्खा को छोड़कर यह आप सेवाओं है कि में उपलब्ध हैं निर्धारित कर सकते हैं की तरह है config चरण। मूल्य नुस्खा का उपयोग करके बनाई गई सेवाओं की तुलना में जल्द ही। मानों के विपरीत, उनका उपयोग करके सजाया नहीं जा सकता decorator
प्रदाता प्रलेखन देखें ।


2
तो सेवा और कारखाने अनिवार्य रूप से एक ही हैं? एक दूसरे का उपयोग करना वैकल्पिक सिंटैक्स के अलावा और कुछ नहीं प्रदान करता है?
मैट

2
@ मैट, हाँ, सेवा एक संक्षिप्त तरीका है जब आपके पास पहले से ही अपना कार्य है जिसे आप एक सेवा के रूप में उजागर करना चाहते हैं। डॉक्स से: myApp.factory ('यूनिकॉर्न लंचर', ["एपीटोकन", फंक्शन (एपीटोकन) {नया यूनिकॉर्न लंचर (apiToken);})); बनाम: myApp.service ('यूनिकॉर्न लंचर', ["एपीटोकन", यूनिकॉर्न लंचर));
जनेक

5
@joshperry एक नौसिखिया के रूप में, मैं थोड़ी देर के लिए सेवा और कारखाने के बीच के अंतर को समाप्त कर चुका हूँ। मैं मानता हूँ कि यह सबसे अच्छा जवाब है! मैं सेवा को सेवा वर्ग (उदाहरण के लिए एनकोडर / डिकोडर वर्ग) के रूप में समझता हूँ, जिसमें कुछ निजी गुण हो सकते हैं। और कारखाना स्टेटलेस हेल्पर विधियों का एक सेट प्रदान करता है।
stanleyxu2005

3
ऊपर दिए गए अन्य उत्तरों में हां के उदाहरण बहुत ही स्पष्ट रूप से मुख्य अंतर b / w सेवाओं और प्रदाताओं को समझाते हैं जो उस समय इन इंजेक्शनों को इंजेक्ट किया जाता है।
आशीष सिंह

223

AngularJS फैक्टरी, सेवा और प्रदाता को समझना

इन सभी का उपयोग पुन: प्रयोज्य एकल वस्तुओं को साझा करने के लिए किया जाता है। यह आपके एप्लिकेशन / विभिन्न घटकों / मॉड्यूल में पुन: प्रयोज्य कोड साझा करने में मदद करता है।

डॉक्स सेवा / फैक्टरी से :

  • आलसी तत्काल - जब कोई अनुप्रयोग घटक उस पर निर्भर करता है, तो कोणीय केवल एक सेवा / फैक्ट्री को तत्काल चालू करता है।
  • सिंगलेट्स - सेवा पर निर्भर प्रत्येक घटक को सेवा कारखाने द्वारा उत्पन्न एकल उदाहरण का संदर्भ मिलता है।

फ़ैक्टरी

एक फैक्ट्री वह फंक्शन है जहां आप ऑब्जेक्ट बनाने से पहले लॉजिक में हेरफेर / जोड़ सकते हैं, फिर नई बनी हुई वस्तु वापस मिलती है।

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

प्रयोग

यह एक वर्ग की तरह केवल कार्यों का एक संग्रह हो सकता है। इसलिए, जब आप इसे अपने कंट्रोलर / फैक्ट्री / डायरेक्टिव फंक्शन्स के अंदर इंजेक्ट कर रहे हैं, तो इसे अलग-अलग कंट्रोलर्स में इंस्टेंट किया जा सकता है। यह एप के अनुसार केवल एक बार इंस्टेंट किया जाता है।

सर्विस

बस सेवाओं को देखते हुए सरणी प्रोटोटाइप के बारे में सोचते हैं। एक सेवा एक फ़ंक्शन है जो 'नए' कीवर्ड का उपयोग करके एक नई वस्तु को त्वरित करता है। आप thisकीवर्ड का उपयोग करके किसी सेवा ऑब्जेक्ट में गुण और फ़ंक्शन जोड़ सकते हैं । एक कारखाने के विपरीत, यह कुछ भी नहीं लौटाता (यह एक वस्तु देता है जिसमें विधियाँ / गुण होते हैं)।

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

प्रयोग

इसका उपयोग तब करें जब आपको पूरे अनुप्रयोग में एक ही वस्तु साझा करने की आवश्यकता हो। उदाहरण के लिए, प्रमाणित उपयोगकर्ता विवरण, शेयर-सक्षम तरीके / डेटा, उपयोगिता कार्य आदि।

प्रदाता

एक प्रदाता का उपयोग एक विन्यास योग्य सेवा ऑब्जेक्ट बनाने के लिए किया जाता है। आप सेवा फ़ंक्शन को कॉन्फ़िगर फ़ंक्शन से कॉन्फ़िगर कर सकते हैं। यह $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या के आधार पर अपना एपीआई URL सेट करना चाहते हैंprod

ध्यान दें

केवल प्रदाता कोणीय के विन्यास चरण में उपलब्ध होगा, जबकि सेवा और कारखाने नहीं हैं।

आशा है कि इसने फैक्ट्री, सेवा और प्रदाता के बारे में आपकी समझ को साफ कर दिया है ।


1
यदि मैं एक विशेष इंटरफ़ेस के साथ एक सेवा करना चाहता था, तो मैं क्या करूंगा, लेकिन दो अलग-अलग कार्यान्वयन हैं, और प्रत्येक को एक नियंत्रक में इंजेक्ट करते हैं लेकिन यूआई-राउटर का उपयोग करके अलग-अलग राज्यों से बंधे हैं? उदाहरण के लिए एक राज्य में दूरस्थ कॉल करें, लेकिन दूसरे में स्थानीय भंडारण के लिए लिखें। प्रदाता डॉक्स का उपयोग करने के लिए कहते हैं only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications, इसलिए संभव नहीं लगता है, है ना?
क्विक्स

191

मेरे लिए, रहस्योद्घाटन तब हुआ जब मुझे एहसास हुआ कि वे सभी एक ही तरह से काम करते हैं: एक बार कुछ चलाने से , उन्हें मिलने वाले मूल्य को संग्रहीत करना और फिर निर्भरता इंजेक्शन के माध्यम से संदर्भित होने पर उसी संग्रहीत मूल्य को खांसी करना ।

कहो हमारे पास:

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

तीन के बीच अंतर यह है कि:

  1. aसंचित मूल्य चलने से आता है fn
  2. bसंग्रहीत मूल्य newआईएनजी से आता है fn
  3. cसंग्रहीत मूल्य पहले newआईएनजी द्वारा आईएनजी द्वारा प्राप्त किया जाता है fn, और फिर $getइंस्टेंस का एक तरीका चल रहा है ।

इसका मतलब है कि एंगुलरजेएस के अंदर कैश ऑब्जेक्ट जैसा कुछ है, जिसका प्रत्येक इंजेक्शन का मूल्य केवल एक बार असाइन किया गया है, जब उन्हें पहली बार इंजेक्ट किया गया है, और जहां:

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

यही कारण है कि हम thisसेवाओं में उपयोग करते हैं, और this.$getप्रदाताओं में परिभाषित करते हैं ।


2
मुझे भी यह जवाब सबसे ज्यादा पसंद है। उन सभी का उद्देश्य जब भी डीआई के माध्यम से किसी वस्तु तक पहुंच प्रदान करना है। आम तौर पर आप factoryएस के साथ ठीक कर रहे हैं । केवल कारण serviceमौजूद हैं जैसे कि CoffeeScript, टाइपस्क्रिप्ट, ES6 आदि भाषाएँ हैं, ताकि आप उनके वर्ग वाक्यविन्यास का उपयोग कर सकें। providerयदि आपके मॉड्यूल का उपयोग विभिन्न सेटिंग्स के साथ कई अनुप्रयोगों में किया जाता है, तो आपको केवल आवश्यकता होती है app.config()। यदि आपकी सेवा एक शुद्ध सिंगलटन है या किसी चीज का उदाहरण बनाने में सक्षम है तो केवल आपके कार्यान्वयन पर निर्भर करता है।
एंड्रियास लिनर्ट

137

सेवा बनाम प्रदाता बनाम कारखाना:

मैं इसे सरल रखने की कोशिश कर रहा हूं। यह मूल जावास्क्रिप्ट अवधारणा के बारे में है।

सबसे पहले, आइए AngularJS में सेवाओं के बारे में बात करते हैं !

क्या है सेवा: एंगुलरजेएस में, सेवाएक सिंगलटन जावास्क्रिप्ट ऑब्जेक्ट के अलावा कुछ भी नहीं है जो कुछ उपयोगी तरीकों या गुणों को संग्रहीत कर सकता है। यह सिंगलटन ऑब्जेक्ट एनजीएपी (एंगुलर ऐप) आधार पर बनाया गया है और इसे वर्तमान ऐप के सभी नियंत्रकों के बीच साझा किया गया है। जब Angularjs एक सेवा ऑब्जेक्ट को तुरंत हटाता है, तो वह इस सेवा ऑब्जेक्ट को एक अद्वितीय सेवा नाम के साथ पंजीकृत करता है। इसलिए हर बार जब हमें सेवा की आवश्यकता होती है, तो कोणीय इस सेवा नाम के लिए रजिस्ट्री खोजता है, और यह सेवा वस्तु का संदर्भ देता है। ऐसा है कि हम सेवा ऑब्जेक्ट पर विधि, पहुंच गुण आदि को लागू कर सकते हैं। आपके पास सवाल हो सकता है कि क्या आप नियंत्रकों की गुंजाइश वस्तु पर गुण, तरीके भी डाल सकते हैं! तो आपको सेवा वस्तु की आवश्यकता क्यों है? उत्तर है: सेवाओं को कई नियंत्रक दायरे में साझा किया जाता है। यदि आप कंट्रोलर के स्कोप ऑब्जेक्ट में कुछ गुण / विधियाँ डालते हैं, तो यह केवल वर्तमान स्कोप के लिए उपलब्ध होगा।

इसलिए अगर तीन कंट्रोलर स्कोप हैं, तो इसे कंट्रोलर, कंट्रोलरबी और कंट्रोलर होने दें, सभी एक ही सर्विस इंस्टेंस को शेयर करेंगे।

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

सेवा कैसे बनाएं?

AngularJS एक सेवा को पंजीकृत करने के लिए विभिन्न तरीके प्रदान करते हैं। यहां हम तीन तरीकों कारखाने (..), सेवा (..), प्रदाता (..) पर ध्यान केंद्रित करेंगे;

कोड संदर्भ के लिए इस लिंक का उपयोग करें

फैक्टरी समारोह:

हम नीचे के रूप में एक कारखाने समारोह को परिभाषित कर सकते हैं।

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

AngularJS 'factory (' serviceName ', fnFactory)' विधि प्रदान करता है जो दो पैरामीटर, सेवानाम और एक जावास्क्रिप्ट फ़ंक्शन लेता है। एंगुलर नीचे दिए गए फ़ंक्शन fnFactory () को लागू करके सेवा उदाहरण बनाता है ।

var serviceInstace = fnFactory();

पारित फ़ंक्शन किसी ऑब्जेक्ट को परिभाषित कर सकता है और उस ऑब्जेक्ट को वापस कर सकता है। AngularJS केवल एक चर के रूप में इस ऑब्जेक्ट संदर्भ को संग्रहीत करता है जिसे पहले तर्क के रूप में पारित किया जाता है। कुछ भी जो fnFactory से लौटाया गया है, सेवा के लिए बाध्य होगा। ऑब्जेक्ट वापस करने के बजाय, हम फ़ंक्शन, मान आदि भी लौटा सकते हैं, हम जो भी वापस करेंगे, वह सेवा उदाहरण के लिए उपलब्ध होगा।

उदाहरण:

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

यह एक और तरीका है, हम एक सेवा को पंजीकृत कर सकते हैं। एकमात्र अंतर यह है कि एंगुलरजेएस किस तरह से सेवा वस्तु को तत्काल भरने की कोशिश करता है। इस बार कोणीय 'नए' कीवर्ड का उपयोग करता है और नीचे दिए गए निर्माण कार्य को कॉल करता है।

var serviceInstance = new fnServiceConstructor();

कंस्ट्रक्टर फ़ंक्शन में हम सेवा ऑब्जेक्ट में गुणों / विधियों को जोड़ने के लिए 'इस' कीवर्ड का उपयोग कर सकते हैं। उदाहरण:

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

प्रदाता समारोह:

प्रदाता () फ़ंक्शन सेवाओं को बनाने का एक और तरीका है। आइए हम एक ऐसी सेवा बनाने के लिए इच्छुक हैं, जो केवल उपयोगकर्ता को कुछ शुभकामना संदेश प्रदर्शित करे। लेकिन हम एक ऐसी कार्यक्षमता भी प्रदान करना चाहते हैं जिससे उपयोगकर्ता अपना ग्रीटिंग संदेश सेट कर सकें। तकनीकी शब्दों में हम विन्यास योग्य सेवाएँ बनाना चाहते हैं। हम ऐसा कैसे कर सकते हैं ? एक रास्ता होना चाहिए, ताकि ऐप अपने कस्टम ग्रीटिंग संदेशों को पारित कर सके और एंगुलरज उसे कारखाने / कंस्ट्रक्टर फ़ंक्शन को उपलब्ध कराएंगे जो हमारी सेवाओं का उदाहरण बनाते हैं। ऐसे मामले में प्रदाता () कार्य करते हैं। प्रदाता () फ़ंक्शन का उपयोग करके हम कॉन्फ़िगर करने योग्य सेवाएं बना सकते हैं।

हम नीचे दिए गए अनुसार सिंटैक्स का उपयोग करके विन्यास योग्य सेवाएँ बना सकते हैं।

/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});

/*step2:configure the service */
app.config(function configureService(serviceProvider){});

प्रदाता सिंटैक्स आंतरिक रूप से कैसे काम करता है?

1.Provider ऑब्जेक्ट हमारे प्रदाता फ़ंक्शन में परिभाषित कंस्ट्रक्टर फ़ंक्शन का उपयोग करके बनाया गया है।

var serviceProvider = new serviceProviderConstructor();

2. हम app.config () में पारित समारोह, निष्पादित हो। इसे कॉन्फ़िगरेशन चरण कहा जाता है, और यहां हमारे पास अपनी सेवा को अनुकूलित करने का एक मौका है।

configureService(serviceProvider);

3. आम तौर पर सेवा उदाहरण $ call of serviceProvider कॉल करके बनाया जाता है।

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

वर्किंग डेमो

सारांश:


फैक्ट्री एक फैक्ट्री फ़ंक्शन का उपयोग करती है जो एक सेवा उदाहरण लौटाता है। serviceInstance = fnFactory ();

सेवा एक कंस्ट्रक्टर फ़ंक्शन का उपयोग करती है और सेवा आवृत्ति बनाने के लिए 'नया' कीवर्ड का उपयोग करके एंगुलर ने इस कंस्ट्रक्टर फ़ंक्शन का उपयोग किया है। serviceInstance = new fnServiceConstructor ();

प्रदाता प्रदाता प्रदाता फ़ंक्शन को परिभाषित करता है, यह प्रदाताकंस्ट्रक्टर फ़ंक्शन एक फ़ैक्ट्री फ़ंक्शन $ get को परिभाषित करता है । सेवा ऑब्जेक्ट बनाने के लिए कोणीय कॉल $ get () मिलता है। प्रदाता सिंटैक्स को तत्काल प्राप्त होने से पहले सेवा ऑब्जेक्ट को कॉन्फ़िगर करने का एक अतिरिक्त लाभ है। serviceInstance = $ get ();


87

जैसा कि कई लोगों द्वारा यहां बताया गया है कि कारखाने, प्रदाता, सेवा और यहां तक ​​कि मूल्य और स्थिरांक एक ही चीज के संस्करण हैं। आप उन providerसभी में अधिक सामान्य विच्छेद कर सकते हैं। इस तरह:

यहां छवि विवरण दर्ज करें

यहाँ लेख इस छवि से है:

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


63

फ़ैक्टरी

आप 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 इसे इंस्टेंट करने के लिए नया कॉल करेगा । यह उदाहरण है कि AngularJS बनाता है जो सेवा के अनुरोध पर कैश और इंजेक्ट किया जाएगा। के बाद से नई सेवा का दृष्टांत के लिए इस्तेमाल किया गया था, कीवर्ड इस वैध है और उदाहरण के लिए संदर्भित करता है।

उदाहरण:

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

56

प्रदाताओं के साथ खेलने के दौरान मुझे कुछ रोचक लगा।

प्रदाताओं और सेवाओं और कारखानों के लिए इंजेक्टेबलों की दृश्यता अलग है। यदि आप एक 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>

45

यह नौसिखिया के लिए बहुत भ्रामक हिस्सा है और मैंने इसे आसान शब्दों में स्पष्ट करने की कोशिश की है

AngularJS सेवा: नियंत्रक में सेवा संदर्भ के साथ उपयोगिता कार्यों को साझा करने के लिए उपयोग किया जाता है। सेवा प्रकृति में सिंगलटन है इसलिए एक सेवा के लिए केवल एक उदाहरण ब्राउज़र में बनाया जाता है और पूरे पृष्ठ में एक ही संदर्भ का उपयोग किया जाता है।

सेवा में, हम इस ऑब्जेक्ट के साथ फ़ंक्शन नाम संपत्ति के रूप में बनाते हैं ।

AngularJS फैक्टरी: का उद्देश्य भी सेवा के समान ही होता है लेकिन इस मामले में हम एक नई वस्तु बनाते हैं और इस ऑब्जेक्ट के गुणों के रूप में फ़ंक्शन जोड़ते हैं और अंत में हम इस ऑब्जेक्ट को वापस करते हैं।

AngularJS प्रदाता: इसका उद्देश्य फिर से वही है लेकिन प्रदाता इसे $ get फ़ंक्शन का आउटपुट देता है।

सेवा, कारखाने और प्रदाता को परिभाषित और उपयोग करना http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider पर समझाया गया है


2
फैक्टरी और प्रदाता भी सिंगलटन ऑब्जेक्ट हैं? कोई भी स्कैन्रीओ जहां फैक्ट्रियों को सेवाओं पर लेने की सिफारिश की जाती है?
सुनील गर्ग

34

मेरे लिए अंतर समझने का सबसे अच्छा और सरल तरीका है:

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

AngularJS कैसे विशेष घटकों (सरलीकृत) को तत्काल तैयार करता है:

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

// factory
var angularFactory = factory(injection);

तो, सेवा के लिए, जो एंगुलरजेएस घटक बन जाता है वह उस वर्ग का ऑब्जेक्ट उदाहरण है जिसे सेवा घोषणा कार्य द्वारा दर्शाया गया है। कारखाने के लिए, यह कारखाना घोषणा समारोह से लौटा परिणाम है। कारखाना सेवा के समान व्यवहार कर सकता है:

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

सोचने का सबसे सरल तरीका निम्नलिखित है:

  • सेवा एक एकल वस्तु उदाहरण है। यदि आप अपने कोड के लिए एक सिंगलटन ऑब्जेक्ट प्रदान करना चाहते हैं तो सेवाओं का उपयोग करें।
  • फैक्टरी एक वर्ग है। यदि आप अपने कोड के लिए कस्टम क्लासेस प्रदान करना चाहते हैं तो फैक्ट्रियों का उपयोग करें (सेवाओं के साथ नहीं किया जा सकता क्योंकि वे पहले से ही इंस्टेंटेड हैं)।

फ़ैक्टरी 'क्लास' का उदाहरण चारों ओर टिप्पणियों में प्रदान किया गया है, साथ ही प्रदाता अंतर भी।


एक सेवा एक सिंगलटन कैसे हो सकती है यदि इसका उपयोग होने पर हर बार इसे तत्काल किया जाए? मैं अपना सिर उसके चारों ओर ले जा सकता हूं ...
joe

सेवा केवल एक बार निर्भरता के समाधान के दौरान त्वरित है, और फिर जब आप इंजेक्टर से सेवा मांगते हैं, तो आपको हमेशा एक ही उदाहरण मिल रहा है। इसे आसानी से यहां देखा जा सकता है: jsfiddle.net/l0co/sovtu55t/1 , कृपया इसे कंसोल से चलाएं। कंसोल दिखाता है कि सेवा केवल एक बार त्वरित है।
लुकाज़ फ्रेंकोव्स्की

ओह मैं समझा। मैं शाब्दिक new MyService()या कुछ करने में सक्षम होने की उम्मीद कर रहा था :)
जो

33

इस मामले पर मेरी सफाई:

मूल रूप से सभी उल्लिखित प्रकार (सेवा, कारखाने, प्रदाता, आदि) पुराने वैरिएबल ग्लोबल वैरिएबल्स के समान ही वैश्विक वैरिएबल्स (जो कि संपूर्ण अनुप्रयोग के लिए निश्चित रूप से वैश्विक हैं) का निर्माण और विन्यास कर रहे हैं।

जबकि वैश्विक चर की सिफारिश नहीं की जाती है, इन वैश्विक चर का वास्तविक उपयोग निर्भरता इंजेक्शन प्रदान करने के लिए होता है , चर को संबंधित नियंत्रक को पास करके।

"वैश्विक चर" के लिए मान बनाने में जटिलताओं के कई स्तर हैं:

  1. लगातार
    यह एक वास्तविक स्थिरांक को परिभाषित करता है जिसे पूरे आवेदन के दौरान संशोधित नहीं किया जाना चाहिए, जैसे अन्य भाषाओं में स्थिरांक (कुछ ऐसा है जिसमें जावास्क्रिप्ट की कमी है)।
  2. मान
    यह एक परिवर्तनीय मूल्य या वस्तु है, और यह कुछ वैश्विक चर के रूप में कार्य करता है, जिसे अन्य सेवाओं या कारखानों को बनाते समय भी इंजेक्ट किया जा सकता है (इन पर आगे देखें)। हालाँकि, यह एक " शाब्दिक मूल्य " होना चाहिए , जिसका अर्थ है कि किसी को वास्तविक मूल्य लिखना होगा, और किसी संगणना या प्रोग्रामिंग तर्क का उपयोग नहीं किया जा सकता है (दूसरे शब्दों में 39 या myText या {prop: "value"} ठीक है, लेकिन 2 +2 नहीं है)।
  3. फैक्टरी
    एक अधिक सामान्य मूल्य, कि तुरंत गणना की जा सकती है। यह AngularJS के मान को गणना करने के लिए आवश्यक तर्क के साथ एक फ़ंक्शन पास करके काम करता है और AngularJS इसे निष्पादित करता है, और यह नामित वैरिएबल में रिटर्न वैल्यू बचाता है।
    ध्यान दें कि एक वस्तु को वापस करना संभव है (जिस स्थिति में यह सेवा के समान कार्य करेगा ) या एक फ़ंक्शन (जिसे कॉलबैक फ़ंक्शन के रूप में चर में सहेजा जाएगा)।
  4. सेवा
    एक सेवा कारखाने का एक अधिक छीन लिया गया संस्करण है जो केवल तभी मान्य होता है जब मूल्य एक वस्तु होती है, और यह फ़ंक्शन में सीधे किसी भी तर्क को लिखने की अनुमति देता है (जैसे कि यह एक निर्माता होगा), साथ ही साथ घोषणा और पहुंच भी। का उपयोग कर वस्तु गुण इस कीवर्ड ।
  5. प्रदाता
    एक सेवा के विपरीत जो कारखाने का सरलीकृत संस्करण है , एक प्रदाता एक अधिक जटिल है, लेकिन "वैश्विक" चर को शुरू करने का अधिक लचीला तरीका है, जिसमें सबसे बड़ा लचीलापन ऐप से मूल्यों को सेट करने का विकल्प है।
    यह सेवा और प्रदाता के संयोजन का उपयोग करने की तरह काम करता है, एक प्रदाता को पास करके जो इस कीवर्ड का उपयोग करके घोषित किए गए गुण हैं , जिसका उपयोग किया जा सकता है app.config
    फिर इसके लिए एक अलग $ .get फ़ंक्शन की आवश्यकता होती है जो app.configफ़ाइल के माध्यम से उपरोक्त गुणों को सेट करने के बाद AngularJS द्वारा निष्पादित किया जाता है , और यह $ $। फ़ंक्शन ठीक उसी तरह व्यवहार करता है। फ़ैक्टरी के समान ऊपर, इसमें "वापसी" का उपयोग "वैश्विक" चर को आरंभ करने के लिए किया गया है।

26

मेरी समझ नीचे बहुत सरल है।

फैक्टरी: आप बस कारखाने के अंदर एक वस्तु बनाते हैं और इसे वापस करते हैं।

सर्विस:

आपके पास एक मानक फ़ंक्शन है जो फ़ंक्शन को परिभाषित करने के लिए इस कीवर्ड का उपयोग करता है।

प्रदाता:

एक $getवस्तु है जिसे आप परिभाषित करते हैं और इसका उपयोग उस वस्तु को प्राप्त करने के लिए किया जा सकता है जो डेटा लौटाता है।


क्या आपने कारखाने और सेवा को मिलाया नहीं? सेवाएँ बनाता है जहाँ कारखाना देता है।
फ्लाविएन वोलेन

जब आप सेवा नाम को एक इंजेक्शन योग्य तर्क के रूप में घोषित करते हैं, तो आपको फ़ंक्शन का एक उदाहरण प्रदान किया जाएगा। दूसरे शब्दों में नया फंक्शन YouPassedToService ()। यह ऑब्जेक्ट उदाहरण सेवा ऑब्जेक्ट बन जाता है जिसे AngularJS पंजीकृत करता है और यदि आवश्यक हो तो अन्य सेवाओं / नियंत्रकों को बाद में इंजेक्ट करता है। // फ़ैक्टरी जब आप फ़ैक्टरीनाम को एक इंजेक्शन योग्य तर्क के रूप में घोषित करते हैं, तो आपको उस मान के साथ प्रदान किया जाएगा, जो मॉड्यूल.फैक्टिंग को पारित फ़ंक्शन संदर्भ को लागू करके वापस किया जाता है।
साजन

ठीक है, तो ... कोणीय में कारखाना एक सिंगलटन है जहां "सेवा" वास्तव में एक कारखाना है (सामान्य डिजाइन पैटर्न के संदर्भ में)
फ्लाविएन वोल्केन

25

कोणीय डॉक्स से सारांश :

  • पाँच नुस्खा प्रकार हैं जो वस्तुओं को बनाने के तरीके को परिभाषित करते हैं: मूल्य , कारखाना , सेवा , प्रदाता और लगातार
  • फैक्टरी और सेवा सबसे अधिक उपयोग की जाने वाली रेसिपी हैं। उनके बीच एकमात्र अंतर यह है कि सेवा नुस्खा कस्टम प्रकार की वस्तुओं के लिए बेहतर काम करता है, जबकि फैक्टरी जावास्क्रिप्ट आदिम और कार्यों का उत्पादन कर सकती है।
  • प्रदाता नुस्खा कोर नुस्खा प्रकार है और अन्य सभी लोगों को उस पर सिर्फ वाक्यात्मक चीनी हैं।
  • प्रदाता सबसे जटिल नुस्खा प्रकार है। जब तक आप वैश्विक कॉन्फ़िगरेशन की आवश्यकता वाले कोड का पुन: प्रयोज्य टुकड़ा बना रहे हैं, तब तक आपको इसकी आवश्यकता नहीं है।

यहां छवि विवरण दर्ज करें


SO से सर्वश्रेष्ठ उत्तर:

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


20

पहले से ही सभी अच्छे जवाब। मैं सेवा और कारखाने पर कुछ और बिंदु जोड़ना चाहूंगा । सेवा / कारखाने के बीच अंतर के साथ। और एक जैसे प्रश्न भी हो सकते हैं:

  1. क्या मुझे सेवा या कारखाने का उपयोग करना चाहिए? क्या फर्क पड़ता है?
  2. क्या वे ऐसा ही करते हैं या एक जैसा व्यवहार करते हैं?

सेवा और कारखाने के बीच अंतर से शुरू करें:

  1. दोनों सिंगलटन हैं : जब भी कोणीय पहली बार एक निर्भरता के रूप में पाते हैं, तो यह सेवा / कारखाने का एक ही उदाहरण बनाता है। एक बार उदाहरण बनने के बाद, एक ही उदाहरण हमेशा के लिए उपयोग किया जाता है।

  2. व्यवहार के साथ एक वस्तु को मॉडल करने के लिए इस्तेमाल किया जा सकता है : वे दोनों तरीकों, आंतरिक राज्य चर, और इतने पर हो सकते हैं। हालाँकि आप जिस तरह से लिखेंगे वह कोड अलग होगा।

सेवाएं:

एक सेवा एक निर्माण कार्य है, और कोणीय नए को कॉल करके इसे त्वरित करेगा yourServiceName()। इसका मतलब है एक दो चीजें।

  1. कार्य और उदाहरण चर के गुण होंगे this
  2. आपको मान वापस करने की आवश्यकता नहीं है। जब कोणीय new yourServiceName() पुकारता है , तो यह thisआपके द्वारा डाले गए सभी गुणों के साथ वस्तु प्राप्त करेगा।

नमूना उदाहरण:

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

जब कोणीय इस 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उदाहरण के लिए, यदि आपने सर्वर से हड़प कर स्कोर को इनिशियलाइज़ किया है, तो आपको एक वादा श्रृंखला में कॉल करने के लिए लुभाया जा सकता है : $http.get('/score').then(ScoreKeeper.setScore).इसके साथ परेशानी यह है कि ScoreKeeper.setScoreइसे thisबाध्य किया जाएगा nullऔर आपको त्रुटियां मिलेंगी। बेहतर तरीका होगा $http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper))। चाहे आप इसे अपनी सेवा विधियों में उपयोग करना चाहें या नहीं, सावधान रहें कि आप उन्हें कैसे बुलाते हैं।

किसी से मान लौटाते हुएService :

जावास्क्रिप्ट कंस्ट्रक्टर कैसे काम करते हैं, इसके कारण यदि आप (i.e., an Object)किसी constructorफ़ंक्शन से एक जटिल मान लौटाते हैं , तो कॉल करने वाले को इस उदाहरण के बजाय ऑब्जेक्ट मिलेगा।

इसका मतलब है कि आप मूल रूप से नीचे दिए गए कारखाने के उदाहरण को कॉपी-पेस्ट कर सकते हैं, इसके factoryसाथ प्रतिस्थापित कर सकते हैं service, और यह काम करेगा:

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

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

इसलिए जब कोणीय नए MyService () के साथ आपकी सेवा का निर्माण करता है, तो उसे MyService उदाहरण के बजाय वह एपी ऑब्जेक्ट मिलेगा।

यह किसी भी जटिल मूल्यों (वस्तुओं, कार्यों) के लिए व्यवहार है, लेकिन आदिम प्रकारों के लिए नहीं।

कारखाना:

एक कारखाना एक पुराना पुराना कार्य है जो एक मूल्य देता है। वापसी मूल्य वह है जो कारखाने में निर्भर चीजों में अंतःक्षिप्त हो जाता है। कोणीय में एक विशिष्ट कारखाना पैटर्न इस तरह के गुणों के रूप में कार्यों के साथ एक वस्तु वापस करने के लिए है:

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

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

  return api;
});

फैक्ट्री निर्भरता के लिए इंजेक्शन का मूल्य फैक्ट्री का रिटर्न वैल्यू है, और इसके लिए कोई वस्तु नहीं है। यह एक समारोह हो सकता है

1 और 2 से ऊपर के सवालों के जवाब:

अधिकांश भाग के लिए, बस हर चीज के लिए कारखानों का उपयोग करने के साथ रहें। उनके व्यवहार को समझना आसान है। इस बारे में कोई विकल्प नहीं है कि कोई मान लौटाया जाए या नहीं, और इसके अलावा, अगर आप गलत काम करते हैं तो कोई बग नहीं पेश किया जाएगा।

मैं अभी भी उन्हें "सेवाओं" के रूप में संदर्भित करता हूं, जब मैं उन्हें निर्भरता के रूप में इंजेक्ट करने के बारे में बात कर रहा हूं, हालांकि।

सेवा / फैक्टरी व्यवहार बहुत समान है, और कुछ लोग कहेंगे कि या तो एक ठीक है। यह कुछ हद तक सही है, लेकिन मुझे जॉन पापा की स्टाइल गाइड की सलाह का पालन करना आसान लगता है और बस कारखानों से चिपकना पड़ता है। **


16

एक अतिरिक्त स्पष्टीकरण यह है कि कारखाने कार्य / आदिम बना सकते हैं, जबकि सेवाएँ नहीं कर सकते। 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/


16

पहले से ही अच्छे उत्तर हैं, लेकिन मैं इसे साझा करना चाहता हूं।

सबसे पहले: प्रदाता एक बनाने का तरीका / नुस्खा हैservice (सिंगलटन ऑब्जेक्ट) जो कि $ इंजेक्टर द्वारा इंजेक्ट किया जाता है (कैसे अंगुलाएस आईओसी पैटर्न के बारे में बताता है)।

और मूल्य, फैक्टरी, सेवा और लगातार (4 तरीके) - प्रदाता मार्ग / रसीद पर सिंटैक्टिक चीनी ।

इसमें Service vs Factoryभाग शामिल किया गया है: https://www.youtube.com/watch?v=BLzNCkPn3ao

सेवाnew वास्तव में कीवर्ड के बारे में है जो हम जानते हैं कि 4 चीजें हैं:

  1. एकदम नई वस्तु बनाता है
  2. इसे अपनी prototypeवस्तु से जोड़ता है
  3. से जोड़ता contextहैthis
  4. और लौटता है this

और फैक्ट्री सभी फैक्ट्री पैटर्न के बारे में है - इसमें ऐसे कार्य शामिल हैं जो उस सेवा की तरह वस्तुओं को वापस करते हैं।

  1. अन्य सेवाओं का उपयोग करने की क्षमता (निर्भरता है)
  2. सेवा आरंभ
  3. विलंबित / आलसी आरंभीकरण

और यह सरल / लघु वीडियो: कवर प्रदाता भी : https://www.youtube.com/watch?v=HvTZbQ_hUZY (वहां आप देख सकते हैं कि वे कारखाने से प्रदाता तक कैसे जाते हैं)

प्रदाता रेसिपी का उपयोग ज्यादातर ऐप कॉन्फिगर में किया जाता है, इससे पहले कि ऐप पूरी तरह से शुरू / शुरू हो जाए।


14

इन सभी पोस्ट को पढ़ने के बाद इसने मेरे लिए और अधिक उलझन पैदा कर दी .. लेकिन अभी भी सभी जानकारी योग्य है .. अंत में मुझे निम्नलिखित तालिका मिली जो सरल तुलना के साथ जानकारी देगी

  • इंजेक्टर व्यंजनों का उपयोग दो प्रकार की वस्तुओं को बनाने के लिए करता है: सेवाएं और विशेष उद्देश्य ऑब्जेक्ट
  • पाँच नुस्खा प्रकार हैं जो वस्तुओं को बनाने के तरीके को परिभाषित करते हैं: मूल्य, कारखाना, सेवा, प्रदाता और लगातार।
  • फैक्टरी और सेवा सबसे अधिक उपयोग की जाने वाली रेसिपी हैं। उनके बीच एकमात्र अंतर यह है कि सेवा नुस्खा एक कस्टम प्रकार की वस्तुओं के लिए बेहतर काम करता है, जबकि फैक्टरी जावास्क्रिप्ट आदिम और कार्यों का उत्पादन कर सकती है।
  • प्रदाता नुस्खा कोर नुस्खा प्रकार है और अन्य सभी इस पर सिर्फ वाक्य रचना चीनी हैं।
  • प्रदाता सबसे जटिल नुस्खा प्रकार है। जब तक आप वैश्विक कॉन्फ़िगरेशन की आवश्यकता वाले कोड का पुन: प्रयोज्य टुकड़ा बना रहे हैं, तब तक आपको इसकी आवश्यकता नहीं है।
  • नियंत्रक को छोड़कर सभी विशेष उद्देश्य ऑब्जेक्ट्स फ़ैक्टरी व्यंजनों के माध्यम से परिभाषित किए गए हैं।

यहां छवि विवरण दर्ज करें

और शुरुआती समझने के लिए: - यह उपयोग के मामले को सही नहीं कर सकता है लेकिन उच्च स्तर में यह इन तीनों के लिए उपयोग है।

  1. यदि आप कोणीय मॉड्यूल में उपयोग करना चाहते हैं तो विन्यास समारोह को प्रदाता के रूप में बनाया जाना चाहिए

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

  1. अजाक्स कॉल या थर्ड पार्टी इंटीग्रेशन को सर्विस देने की जरूरत है ।
  2. डेटा जोड़तोड़ के लिए इसे कारखाने के रूप में बनाएं

बुनियादी परिदृश्यों के लिए कारखाने और सेवा समान व्यवहार करते हैं।


13

यहाँ कुछ ब्रायलरप्लेट कोड है जो मैं AngularjS में ऑब्जेक्ट फैक्ट्री के लिए एक कोड-टेम्पलेट के रूप में लेकर आया हूँ। मैंने उदाहरण के रूप में वर्णन करने के लिए एक कार / 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>

यहाँ एक सरल उदाहरण है। मैं कुछ तीसरे पक्ष के पुस्तकालयों का उपयोग कर रहा हूं जो अक्षांश और देशांतर को उजागर करने वाले "स्थिति" ऑब्जेक्ट की अपेक्षा करते हैं, लेकिन विभिन्न ऑब्जेक्ट गुणों के माध्यम से। मैं विक्रेता कोड को हैक नहीं करना चाहता था, इसलिए मैंने "स्थिति" वस्तुओं को समायोजित किया जो मैं चारों ओर से गुजर रहा था।

    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

;


12

इस पृष्ठ और दस्तावेज के संदर्भ के रूप में उपयोग करना (जो कि पिछली बार जब मैंने देखा था तब से बहुत सुधार हुआ है) लगता है, मैंने निम्नलिखित वास्तविक (-ish) विश्व डेमो को एक साथ रखा है जो प्रदाता के 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);
    };
});

वर्किंग डेमो


12

यह उत्तर विषय / प्रश्न को संबोधित करता है

कैसे कारखाने, सेवा और लगातार - एक प्रदाता नुस्खा के शीर्ष पर सिर्फ वाक्यात्मक चीनी हैं?

या

कैसे कारखाने, सामान्य और प्रदाताओं simailar आंतरिक रूप से हैं

मूल रूप से जो होता है

जब आप factory()इसे सेट करते हैं तो आप functionप्रदाता को दूसरे तर्क में प्रदान करते हैं $getऔर इसे वापस करते हैं ( provider(name, {$get:factoryFn })), आपको जो भी मिलता है वह है, providerलेकिन इसके अलावा कोई संपत्ति / विधि नहीं$get है provider(इसका मतलब है कि आप इसे कॉन्फ़िगर नहीं कर सकते हैं)

कारखाने का स्रोत कोड

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

जब एक बनाने service()यह आप एक साथ एक (कारखाना) उपलब्ध कराने के लौटने functionकि injects constructorऔर यह रिटर्न (निर्माता आप अपनी सेवा में प्रदान की जाती के कहने वापसी)

सेवा का स्रोत कोड

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

तो मूल रूप से दोनों मामलों में आपको अंततः एक प्रदाता मिलता है, जो आपके द्वारा प्रदान किए गए फ़ंक्शन पर सेट हो जाता है, लेकिन आप मूल रूप से इनवॉइस ब्लॉक के लिए प्रदाता () में प्रदान करने के लिए $ $ से अधिक कुछ भी दे सकते हैं।


11

मैं बहुत सारे उत्कृष्ट उत्तर जानता हूं, लेकिन मुझे
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;
... 

10

पार्टी के लिए थोड़ी देर। लेकिन मुझे लगा कि फैक्ट्री, सर्विस और प्रोवाइडर मेथडॉलजी का उपयोग करके कोणीय जेएस कस्टम सर्विसेज विकसित करने के बारे में यह सीखना (या स्पष्टता) चाहने वालों के लिए यह अधिक उपयोगी है।

मुझे इस वीडियो के बारे में पता चला, जो कि 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;
  }
]);

कस्टम सेवाओं के लिए "सेवा" कार्यप्रणाली के लिए कोड (यह 'कारखाने' के समान है, लेकिन वाक्यविन्यास के दृष्टिकोण से अलग है):

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

अंत में यूआई जो उपरोक्त सेवाओं में से किसी के साथ काम करता है:

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


10

बस चीजों को स्पष्ट करने के लिए, AngularJS स्रोत से, आप एक सेवा देख सकते हैं बस कारखाने फ़ंक्शन को कॉल करता है जो बदले में प्रदाता फ़ंक्शन को कॉल करता है:

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

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

9

आइए एक सरल तरीके से एंगुलरजेएस में व्यावसायिक तर्क को संभालने के तीन तरीकों पर चर्चा करें: ( याकोव के कसेरा एंगुलरजेएस पाठ्यक्रम से प्रेरित )

सेवा :

वाक्य - विन्यास:

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. आलसी त्वरित : यदि इसे इंजेक्ट नहीं किया जाता है तो यह कभी भी त्वरित नहीं होगा। इसलिए इसका उपयोग करने के लिए इसे एक मॉड्यूल में इंजेक्ट करना होगा।
  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()पद्धति का उपयोग आमतौर पर किसी चीज़ के लिए एक शॉर्टकट के रूप में किया जाता है जिसे किसी भी कॉन्फ़िगरेशन की आवश्यकता नहीं होती है।

प्रदाता

आइए, पहले सिंटैक्स पर एक नज़र डालते हैं:

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. प्रदाता कोणीय में सेवाएं बनाने का सबसे लचीला तरीका है।
  2. न केवल हम एक ऐसी फैक्ट्री बना सकते हैं जो डायनेमिक रूप से कंफर्टेबल हो, लेकिन प्रोवाइडर विधि के साथ फैक्ट्री के उपयोग के समय, हम कस्टम को हमारे पूरे एप्लिकेशन के बूटस्ट्रैपिंग के समय सिर्फ एक बार फैक्ट्री को कॉन्फ़िगर कर सकते हैं।
  3. कारखाने को कस्टम सेटिंग्स के साथ पूरे एप्लिकेशन में उपयोग किया जा सकता है। दूसरे शब्दों में, आवेदन शुरू होने से पहले हम इस कारखाने को कॉन्फ़िगर कर सकते हैं। कोणीय दस्तावेज में वास्तव में यह उल्लेख किया गया है प्रदाता विधि क्या वास्तव में पर्दे के पीछे निष्पादित हो जाता है जब हम किसी के साथ हमारी सेवाओं कॉन्फ़िगर है कि .serviceया .factoryतरीकों।
  4. $getएक समारोह है कि सीधे प्रदाता उदाहरण से जुड़ा हुआ है है। वह फंक्शन एक फैक्ट्री फंक्शन है। दूसरे शब्दों में, यह उस विधि की तरह ही है जिसका हम उपयोग करते हैं.factory । उस फ़ंक्शन में, हम अपनी स्वयं की सेवा बनाते हैं। यह $getसंपत्ति, जो एक फ़ंक्शन है, वह है जो प्रदाता को एक प्रदाता बनाती हैएंगुलरजेएस को उम्मीद है कि प्रदाता को एक $ संपत्ति मिलेगी जिसका मूल्य एक फ़ंक्शन है जिसे एंगुलर कारखाने के कार्य के रूप में मानेगा। लेकिन जो इस पूरे प्रदाता सेटअप को बहुत खास बनाता है, वह तथ्य यह है कि हम configसेवा प्रदाता के अंदर कुछ वस्तु प्रदान कर सकते हैं , और यह आमतौर पर चूक के साथ आता है कि हम बाद में कदम में ओवरराइट कर सकते हैं, जहां हम पूरे एप्लिकेशन को कॉन्फ़िगर कर सकते हैं।

7

फैक्ट्री: फैक्ट्री आप वास्तव में फैक्ट्री के अंदर एक वस्तु बनाते हैं और उसे वापस करते हैं।
सेवा: आपके पास बस एक मानक फ़ंक्शन है जो फ़ंक्शन को परिभाषित करने के लिए इस कीवर्ड का उपयोग करता है।
प्रदाता: प्रदाता एक $ प्राप्त होता है जिसे आप परिभाषित करते हैं और इसका उपयोग उस वस्तु को प्राप्त करने के लिए किया जा सकता है जो डेटा लौटाता है।


7

अनिवार्य रूप से, प्रदाता, कारखाने और सेवा सभी सेवाएँ हैं। एक फैक्ट्री एक सेवा का एक विशेष मामला है जब आपको ज़रूरत होती है एक $ get () फ़ंक्शन, जो आपको इसे कम कोड के साथ लिखने की अनुमति देता है।

सेवाओं, कारखानों और प्रदाताओं के बीच प्रमुख अंतर उनकी जटिलताएं हैं। सेवाएं सबसे सरल रूप हैं, फैक्टरियां थोड़ी अधिक मजबूत हैं, और प्रदाता रनटाइम पर कॉन्फ़िगर करने योग्य हैं।

यहाँ प्रत्येक का उपयोग करने का सारांश दिया गया है:

फैक्टरी : आपके द्वारा प्रदान किए जा रहे मूल्य की गणना अन्य डेटा के आधार पर की जानी चाहिए।

सेवा : आप विधियों के साथ एक वस्तु लौटा रहे हैं।

प्रदाता : आप कॉन्फ़िगर करने में सक्षम होना चाहते हैं, कॉन्फ़िगरेशन चरण के दौरान, वह वस्तु जो बनने से पहले बनाई जाने वाली है। ऐप को पूरी तरह से इनिशियलाइज़ करने से पहले प्रोवाइडर का इस्तेमाल ज्यादातर ऐप कॉन्फिगर में करें।


ईआरएम। मूल्य, फैक्टरी, सेवा और लगातार - एक प्रदाता नुस्खा के शीर्ष पर सिंटैक्टिक चीनी हैं। AngularJS डॉक्स - प्रदाताओं
Sudarshan_SMD

हाँ मैं सहमत हूँ, अब कोणीय 4 के साथ हमारे पास यह सिरदर्द नहीं है
eGhoul

4

1. सेवा एकल ऑब्जेक्ट हैं जो आवश्यक होने पर बनाए जाते हैं और अनुप्रयोग जीवन-चक्र (जब ब्राउज़र बंद होता है) के अंत तक कभी भी साफ नहीं किया जाता है। नियंत्रकों को तब नष्ट और साफ़ कर दिया जाता है, जब उनकी आवश्यकता नहीं होती है।

2. फैक्ट्री () विधि का उपयोग करके सेवा बनाने का सबसे आसान तरीका है। फैक्ट्री () पद्धति हमें एक सेवा को परिभाषित करने की अनुमति देती है जिसमें सेवा फ़ंक्शन और सेवा डेटा शामिल हैं। सेवा परिभाषा फ़ंक्शन वह जगह है जहां हम अपनी इंजेक्टेबल सेवाओं जैसे $ 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; });

हमारे ऐप में कारखाने () का उपयोग करना

हमारे आवेदन में कारखाने का उपयोग करना आसान है क्योंकि हम बस इसे इंजेक्ट कर सकते हैं जहां हमें रन-टाइम पर इसकी आवश्यकता होती है।

angular.module('myApp')
.controller('MainController', function($scope, User) {
  $scope.saveUser = User.save;
});
  1. दूसरी ओर सेवा () विधि, एक कंस्ट्रक्टर फ़ंक्शन को परिभाषित करके हमें एक सेवा बनाने की अनुमति देती है। कच्ची जावास्क्रिप्ट वस्तु के बजाय हम अपनी सेवा को परिभाषित करने के लिए एक प्रोटोटाइप ऑब्जेक्ट का उपयोग कर सकते हैं। कारखाने () विधि के समान, हम फ़ंक्शन परिभाषा में इंजेबल्स भी सेट करेंगे।
  2. सेवा प्रदान करने का सबसे निचला स्तर तरीका () विधि का उपयोग करके है। यह एक सेवा बनाने का एकमात्र तरीका है जिसे हम .config () फ़ंक्शन का उपयोग करके कॉन्फ़िगर कर सकते हैं। पिछली विधियों के विपरीत, हम इंजेक्टेबल्स को एक परिभाषित इस में सेट करेंगे। $ get () फ़ंक्शन परिभाषा।

-3

सिंथेटिक शुगर का अंतर है । केवल प्रदाता की जरूरत है। या दूसरे शब्दों में केवल प्रदाता ही वास्तविक कोणीय है, अन्य सभी व्युत्पन्न हैं (कोड को कम करने के लिए)। एक साधारण संस्करण भी है, जिसे वैल्यू () कहा जाता है, जो सिर्फ मूल्य, कोई गणना या फ़ंक्शन नहीं देता है। यहां तक ​​कि मूल्य प्रदाता से प्राप्त होता है!

इसलिए ऐसी जटिलताएँ, हम प्रदाता का उपयोग क्यों नहीं कर सकते हैं और बाकी सब कुछ भूल सकते हैं? यह हमें आसानी से कोड लिखने और बेहतर संवाद करने में मदद करने वाला है। और टॉगल-इन-गाल उत्तर होगा, जितना अधिक जटिल हो जाएगा उतना ही बेहतर होगा एक फ्रेमवर्क बेचना।


  • एक प्रदाता जो मान = मान लौटा सकता है
  • एक प्रदाता जो बस तुरंत लौट सकता है और वापस लौट सकता है = फैक्टरी (+ मूल्य)
  • एक प्रदाता जो कुछ कर सकता है + कुछ = सेवा (+ फैक्टरी, + मूल्य)
  • एक प्रदाता = में $ get (+ फ़ैक्टरी, + सेवा, + मान) नामक एक संपत्ति होनी चाहिए

कोणीय इंजेक्शन हमें इस निष्कर्ष पर पहुंचने का पहला संकेत देता है।

"$ इंजेक्टर का उपयोग प्रदाता द्वारा परिभाषित वस्तु उदाहरणों को प्राप्त करने के लिए किया जाता है " सेवा नहीं, कारखाना नहीं बल्कि प्रदाता।

और एक बेहतर जवाब यह होगा: "एक सेवा कारखाने द्वारा एक कोणीय सेवा बनाई जाती है। ये सेवा कारखाने ऐसे कार्य हैं जो बदले में, एक सेवा प्रदाता द्वारा बनाए जाते हैं। सेवा प्रदाता निर्माण कार्य करते हैं। जब उन्हें तत्काल संपत्ति मिलनी चाहिए। $ $ कहा जाता है, जो सेवा कारखाने का कार्य करता है। "

तो मास्टर प्रदाता और इंजेक्टर और सब जगह गिर जाएगा :)। और यह टाइपस्क्रिप्ट में दिलचस्प हो जाता है जब $ एक प्रदाता में IServiceProvider से विरासत में प्राप्त किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.