2015-01-11 8 views
6

मैं एक यूआई रूटर कुछ इस तरह (सादगी के लिए छंटनी की) में परिभाषित किया गया है का उपयोग करते हुए:AngularJS यूआई रूटर में कारखाना/सेवा का संकल्प निर्भरता

$stateProvider 
     .state('someState', { 
      resolve: { 
       model: ['modelService', 'info', function (modelService, info) { 
        return modelService.get(info.id).$promise; 
       }] 
      }, 
      controller: 'SomeController' 
     }); 

यह someState राज्य एक कारखाने उपयोग कर रहा है/सेवा है जो कि model पर निर्भर है हल। यह कुछ इस तरह परिभाषित किया है, और AngularJS एक अज्ञात प्रदाता फेंकता है: modelProvider < - मॉडल < - someService त्रुटि यहाँ:

angular 
    .module('someModule') 
    .factory('someService', someService); 

someService.$inject = ['model']; 
function someService(model) { ... } 
इस राज्य के नियंत्रक के अंदर

हालांकि, एक ही model संकल्प का उपयोग कर काम करता है ठीक:

SomeController.$inject = ['model']; 
function SomeController(model) { ... } 

तो मैं समझ रहा है कि यूआई रूटर जब तक संकल्प, क्या हो रहा है जो AngularJS एक त्रुटि फेंक नहीं करने की अनुमति देता SomeController की डि में देरी कर रहा है। हालांकि, someService पर निर्भरता के रूप में उस संकल्प को डालते समय भी वही विलंब नहीं हो रहा है? संकल्प केवल नियंत्रकों पर काम करते हैं? और यदि ऐसा है, तो मैं कारखाने/सेवा के अंदर एक संकल्प का उपयोग कैसे कर सकता हूं?

+0

जो आप पूछ रहे हैं वह सभी एक बहुत ही परिपत्र निर्भरता श्रृंखला की तरह लग रहा है। सेवा को संकल्प पर निर्भर होने की आवश्यकता नहीं होगी, लेकिन – charlietfl

उत्तर

14

क्या संकल्प केवल नियंत्रकों पर काम करते हैं?

हां, केवल नियंत्रकों पर ही काम करता है।

और यदि ऐसा है, तो मैं कारखाने/सेवा के अंदर एक समाधान का उपयोग कैसे कर सकता हूं?

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

में दूसरे शब्दों:

angular.module('someModule') 
.factory('SomeFactory' , function() { 
    // this code only runs once 
    object = {} 
    object.now = Date.now(); 
    return object 
); 

SomeFactory.now वर्तमान समय पहली बार कारखाने एक नियंत्रक में इंजेक्ट किया जाता हो जाएगा, लेकिन यह नहीं बाद के उपयोग पर अद्यतन।

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

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

angular.module('someModule') 
.factory('SomeFactory', function() { 
    return { 
    doSomethingWithModel: function (model) { 
     $http.post('wherever', model); 
    } 
}); 
.controller('SomeController', function (SomeFactory, model) { 
    SomeFactory.doSomethingWithModel(model); 
}); 

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

अमूर्त वार्तालाप के साथ अधिक विस्तृत होना मुश्किल है, इसलिए यदि आपको और पॉइंटर्स की आवश्यकता है तो एक विशिष्ट उपयोग-केस प्रदान करें।

+0

को हल करते समय आप डेटा को वापस बाध्य कर सकते हैं धन्यवाद, यह समझ में आता है और मुझे उस तरह का "लाइटबुल" पल था जिसने आपको याद दिलाया कि कारखानों/सेवाएं सिंगलटन हैं । मुझे यकीन नहीं है कि मैंने पहले उस कनेक्शन को कैसे याद किया था। – Amberite

1

आप सेवाओं या कारखानों में संकल्पित मूल्यों का उपयोग नहीं कर सकते हैं, केवल नियंत्रक में जो हल किए गए मानों के समान राज्य से संबंधित है। सेवाओं और कारखानों सिंगलटन हैं और नियंत्रक नए (तत्काल मामले में) एक राज्य या कहीं और जहां एनजी-नियंत्रक का उपयोग किया जाता है, के लिए तत्काल स्थापित किया जाता है।

तत्कालता $ नियंत्रक सेवा के साथ होती है जो केवल उस नियंत्रक से संबंधित वस्तुओं को इंजेक्ट करने में सक्षम है। सेवाओं और कारखानों में यह क्षमता नहीं है।

1

आप निर्भरता इंजेक्शन पर angular docs समीक्षा करनी चाहिए: जैसी सेवाएं निर्देशों, फिल्टर, और एनिमेशन

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

तो प्रत्येक प्रकार के कोणीय घटक में इंजेक्ट करने के लिए स्वीकार्य घटकों की अपनी सूची होती है। चूंकि सेवाएं सिंगलेट हैं, इसलिए वास्तव में किसी संकल्प के हिस्से के रूप में मूल्य को इंजेक्ट करने का कोई अर्थ नहीं होगा। यदि आपके पृष्ठ पर दो अलग-अलग स्थान थे जो विभिन्न समाधानों के साथ एक सेवा का उपयोग करते थे, तो परिणाम अनिश्चित होगा। यह आपकी सेवा में $scope इंजेक्शन से अधिक समझ नहीं पाएगा। यह नियंत्रकों के लिए समझ में आता है क्योंकि नियंत्रक पृष्ठ के उसी क्षेत्र के लिए ज़िम्मेदार है जिसे हल किया जा रहा है।

यदि आपके someService को मॉडल में डेटा का उपयोग करने की आवश्यकता है, तो इसमें एक ऐसा फ़ंक्शन होना चाहिए जो डेटा को पैरामीटर के रूप में ले ले और आपके नियंत्रक को इसे पास करना चाहिए।

3

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

service-vs-provider-vs-factory

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

मान लीजिए कि हमारे पास वैश्विक app चर पर हमारा कोणीय मॉड्यूल है।पहले हम एक संकल्प विशेषता के साथ Ui-रूटर राज्य बनाने:

app.config(function ($stateProvider) { 
$stateProvider 
    .state('example', { 
    url: '/example', 
    templateUrl: 'app/example/example.html', 
    controller: 'ExampleCtrl', 
    resolve: { 
     repeatValue: ['$q', '$timeout', function($q, $timeout){ 
      var deferred = $q.defer(); 
      $timeout(function(){ 
       deferred.resolve(parseInt(Math.random() * 100)); 
      }, 3000); 
      return deferred.promise; 
     }] 
    } 
    }); 
}); 

एक अतुल्यकालिक कार्रवाई हम reslove वस्तु पर एक वादा वापस जाने के लिए कोणीय कोर द्वारा प्रदान की $q और $timeout सेवा का उपयोग कर रहे हैं, जो संकल्प लिया जाता प्रतिनिधित्व करने के लिए तीन सेकंड के बाद।

app.factory('Greeter', function() { 
// Function 
var Greeter = function(repeat){ 
    this.repeat = repeat; 
}; 

// Prototype 
Greeter.prototype.repeatedHi = function() { 
    var array = []; 
    console.log(this); 
    for (var i = 0; i < this.repeat; i++){ 
    array.push('Hi'); 
    } 
    return array; 
}; 

// Public API here 
return Greeter; 
}); 

यहाँ हम एक निर्माता के रूप में Greeter कारखाना बनाया:

अब हम पहले समझाया पद्धति का उपयोग करके हमारे कारखाने बनाने के लिए की जरूरत है। अब हम इस कारखाने को हमारे द्वारा दिए गए तर्कों को पारित कर सकते हैं। इस उदाहरण में हमें repeat मान के साथ निर्माता प्रदान करने की आवश्यकता है। हम कारखाने के लिए एक अतुल्यकालिक मूल्य सुई, एक ui-राज्य के resolve संपत्ति से लाभ लेने के लिए चाहते हैं, तो हम नियंत्रक पर ऐसा कर सकते हैं:

app.controller('ExampleCtrl', function ($scope, Greeter, repeatValue) { 
    $scope.repeatValue = repeatValue; 

    var greeter = new Greeter(repeatValue); 

    $scope.greetingsArray = greeter.repeatedHi(); 
}); 

$scope.greetingsArray "की repeatValue से भर दिया जाएगा हाय "तार।

मुझे उम्मीद है कि मैंने खुद को स्पष्ट कर दिया है, उम्मीद है कि इससे मदद मिलती है।

+0

महान पद के लिए धन्यवाद। मैं कारखाने को नियंत्रक से तत्काल उदाहरण में बनाने के पहले सोच रहा था, हालांकि मुझे यकीन नहीं था कि यह एक विरोधी पैटर्न था। – Amberite

संबंधित मुद्दे