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


ए के बीच मतभेद क्या हैं Service, Provider तथा Factory AngularJS में?


3167
2018-03-27 17:59


मूल


मैंने पाया कि सभी कोणीय शब्द शुरुआती लोगों के लिए डरा रहे थे। हमने इस चीटशीट से शुरुआत की जो हमारे प्रोग्रामर को कोणीय सीखते समय समझने के लिए थोड़ा आसान था demisx.github.io/angularjs/2014/09/14/...। उम्मीद है कि यह आपकी टीम को भी मदद करता है। - demisx
मेरी राय में, अंतर को समझने का सबसे अच्छा तरीका कोणीय के अपने दस्तावेज़ का उपयोग कर रहा है: docs.angularjs.org/guide/providers यह बेहद अच्छी तरह से समझाया गया है और इसे समझने में आपकी सहायता के लिए एक असाधारण उदाहरण का उपयोग करता है। - Rafael Merlin
@ ब्लाइज धन्यवाद! पोस्ट में मेरी टिप्पणी के अनुसार, मैंने जानबूझकर इसे छोड़ दिया, क्योंकि मेरे अनुभव से 99% उपयोग मामलों को सफलतापूर्वक संभाला जा सकता है service.factory। इस विषय को आगे जटिल नहीं करना चाहते थे। - demisx
मुझे यह चर्चा भी बहुत उपयोगी लगता है stackoverflow.com/questions/18939709/... - Anand Gupta
यहां कुछ अच्छे जवाब दिए गए हैं कैसे services, factories तथा providers काम करता है। - Mistalis


जवाब:


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

फिर हम इस तरह नियंत्रक में 'greeter' के लिए पूछ सकते हैं

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

2803
2017-07-30 10:20



यह भी देखें stackoverflow.com/a/13763886/215945 जो सेवा और कारखाने के बीच मतभेदों पर चर्चा करता है। - Mark Rajcok
संपादन 611 में मैंने कोणीय स्थिरांक और मूल्यों का उपयोग जोड़ा। पहले से दिखाए गए दूसरे के मतभेदों का प्रदर्शन करने के लिए। jsbin.com/ohamub/611/edit - Nick
हालांकि फ़ंक्शन का उदाहरण बनाकर एक सेवा को बुलाया जाता है। यह वास्तव में प्रति इंजेक्टर केवल एक बार बनाया जाता है जो इसे सिंगलटन की तरह बनाता है।docs.angularjs.org/guide/dev_guide.services.creating_services - angelokh
यह उदाहरण अविश्वसनीय हो सकता है अगर यह स्पष्ट व्यावहारिक उदाहरण का उपयोग करता है। मैं यह समझने की कोशिश कर रहा हूं कि चीजों की बात क्या है toEqual तथा greeter.Greet है। थोड़ा और वास्तविक और संबंधित कुछ का उपयोग क्यों न करें? - Kyle Pennell
फ़ंक्शन की अपेक्षा करना () कुछ समझाने के लिए एक खराब विकल्प है। अगली बार असली दुनिया कोड का प्रयोग करें। - Craig


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

"हैलो वर्ल्ड" उदाहरण के साथ 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>


797
2018-05-15 15:53



नहीं करता है this में संदर्भ बदलें $get समारोह? - अब आप उस फ़ंक्शन में तत्काल प्रदाता का संदर्भ नहीं लेते हैं। - Nate-Wilkins
@Nate: this वास्तव में संदर्भ नहीं बदलता है, क्योंकि क्या कहा जा रहा है new Provider()$ प्राप्त करें (), जहां Provider समारोह पारित किया जा रहा है app.provider। यही कहना है $get() निर्माण पर एक विधि के रूप में कहा जा रहा है Provider, इसलिए this देखेंगे Provider जैसा कि उदाहरण बताता है। - Brandon
@ ब्रैंडन ओह ठीक है कि फिर साफ है। पहली नज़र में उलझन में - स्पष्टीकरण के लिए धन्यवाद! - Nate-Wilkins
मुझे क्यों मिलता है Unknown provider: helloWorldProvider <- helloWorld स्थानीय रूप से यह कब चल रहा है? इसे दोबारा टिप्पणी करते हुए, अन्य 2 उदाहरणों के लिए एक ही त्रुटि। क्या कुछ छुपा प्रदाता विन्यास है? (कोणीय 1.0.8) - मिला: stackoverflow.com/questions/12339272/... - Antoine
यही कारण है कि @ एंटोनी को "अज्ञात प्रदान करें: हैलोवर्ल्डप्रोवाइडर" त्रुटि मिलती है क्योंकि आपके .config कोड में, आप 'हैलोवर्ल्डप्रोवाइडर' का उपयोग करते हैं, लेकिन जब आप प्रदाता को myApp.provider ('helloWorld', function ()) में परिभाषित करते हैं, तो आप इसका उपयोग करते हैं 'नमस्ते दुनिया'? दूसरे शब्दों में, आपके कॉन्फ़िगरेशन कोड में, कोणीय कैसे पता चलता है कि आप हैलो वर्ल्ड प्रदाता का जिक्र कर रहे हैं? धन्यवाद - jmtoung


टी एल; डॉ 

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

जब हम अपने नियंत्रक में '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;
});

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

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

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

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

नीचे setArtist एक कलाकार स्वीकार करता है और आपको कलाकार सेट करने की अनुमति देता है। getArtist कलाकार लौटाता है। callItunes यूआरएल बनाने के लिए पहले makeUrl () को कॉल करता है जिसे हम अपने $ http अनुरोध के साथ उपयोग करेंगे। फिर यह एक वादा ऑब्जेक्ट स्थापित करता है, हमारे अंतिम यूआरएल के साथ $ http अनुरोध करता है, क्योंकि $ http एक वादा देता है, हम अपने अनुरोध के बाद .sccess या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' से डेटा के साथ हमारे $ स्कोप ऑब्जेक्ट पर गुण सेट करते हैं। उपर्युक्त एकमात्र मुश्किल कोड यह है कि यदि आपने पहले कभी वादे का सामना नहीं किया है। चूंकि कॉलइट्यून्स एक वादा वापस कर रहा है, इसलिए हम आईथ्यून्स डेटा के साथ पूरा होने के बाद .then () विधि का उपयोग करने में सक्षम होते हैं और केवल $ scope.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 () को कॉल करते हैं तो दुभाषिया कहता है "ठीक है, मैं अभी 'टायलर' ऑब्जेक्ट को देखने जा रहा हूं जिसे हमने अभी बनाया है, 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;
  }

});

अब हमारे कारखाने की तरह, सेट आर्टिस्ट, getArtist, और callItunes जो भी नियंत्रक हम अपनी सेवा पास करते हैं, उसमें उपलब्ध होंगे। यहां मेरा सेवा नियंत्रक है (जो लगभग हमारे कारखाने नियंत्रक के समान ही है)।

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

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

3) प्रदाता

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

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

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 () फ़ंक्शन से वापस किया जाता है। नीचे दिया गया कोड $ 'इस' पर मिलता है (जिसे हम जानते हैं कि अंततः उस फ़ंक्शन से वापस आ जाएगा)। अब, वह $ फ़ंक्शन फ़ंक्शन उन सभी विधियों / गुणों को लौटाता है जिन्हें हम नियंत्रक में उपलब्ध करना चाहते हैं। यहां एक कोड उदाहरण है।

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

अब हमारे कारखाने और सेवा की तरह, सेट आर्टिस्ट, getArtist, और callItunes जो भी नियंत्रक हम पास करते हैं, उसमें उपलब्ध होगा। यहां मेरा प्रदाता नियंत्रक है (जो लगभग हमारे कारखाने / सेवा नियंत्रक के समान ही है)।

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 फ़ंक्शन के माध्यम से कुछ चर बदलने में सक्षम होना है। आइए इसका एक उदाहरण देखें।

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

अब आप देख सकते हैं कि कैसे 'चीज़फ्रॉम कॉन्फिग' हमारे प्रदाता में खाली स्ट्रिंग है, लेकिन जब यह डोम में दिखाई देता है, तो यह 'यह वाक्य सेट किया गया था ...'।


619
2017-12-24 13:15



इस उत्कृष्ट लेखन में लापता एकमात्र हिस्सा कारखाने पर सेवा का उपयोग करने के सापेक्ष फायदे हैं; जिसे लियोर द्वारा स्वीकृत उत्तर में स्पष्ट रूप से समझाया गया है - infinity
एफडब्ल्यूआईडब्ल्यू (शायद ज्यादा नहीं), यहां एक ब्लॉगर है जो कोणीय के साथ समस्या उठाता है, और प्रदाता प्रदाता पसंद नहीं करता है codeofrob.com/entries/you-have-ruined-javascript.html - barlop
'जावास्क्रिप्ट गुरु' पंचलाइन थी। : डी मुझे लगता है कि यह जवाब चीजों को बहुत साफ करता है। शानदार लिखा है। - amarmishra
आपके टीएलडीआर को एक टीएलडीआर की जरूरत है। - JensB
@ जेन्सबी टीएल; डॉ - प्रतिक्रिया जानें। - Tyler McGinnis


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

value, factory, service, constant, तथा provider विधियां सभी प्रदाता हैं। वे इंजेक्टर को सेवाओं को तुरंत चालू करने के लिए सिखाते हैं।

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

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

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


506
2018-02-01 12:58



तो सेवा और कारखाने अनिवार्य रूप से वही हैं? एक दूसरे का उपयोग वैकल्पिक वाक्यविन्यास के अलावा कुछ भी नहीं प्रदान करता है? - Matt
@ मैट, हाँ, सेवा एक संक्षिप्त तरीका है जब आपके पास पहले से ही अपना कार्य है जिसे आप सेवा के रूप में बेनकाब करना चाहते हैं। दस्तावेज़ों से: myApp.factory ('unicornLauncher', ["apiToken", फ़ंक्शन (apiToken) {वापसी नया यूनिकॉर्नलाउचर (apiToken);}]); बनाम: myApp.service ('unicornLauncher', ["apiToken", यूनिकॉर्नलाउचर]); - janek
@joshperry एक नौसिखिया के रूप में, मैंने थोड़ी देर के लिए सेवा और कारखाने के बीच अंतर गुमराह किया है। मैं मानता हूं कि यह अब तक का सबसे अच्छा जवाब है! मैं एक सेवा वर्ग (जैसे एन्कोडर / डिकोडर कक्षा) के रूप में सेवा को समझूंगा, जिसमें कुछ निजी गुण हो सकते हैं। और कारखाना स्टेटलेस सहायक विधियों का एक सेट प्रदान करता है। - stanleyxu2005
हां अन्य उपरोक्त उत्तरों में उदाहरण मुख्य अंतर बी / डब्ल्यू सेवाओं और प्रदाताओं को स्पष्ट रूप से स्पष्ट करने में विफल रहते हैं, जब इन व्यंजनों को तत्कालित किया जाता है। - Ashish Singh


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

प्रयोग

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

सर्विस

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