2013-08-22 6 views
6

से पहले लोड करता है, मैं इस तथ्य के साथ इसका प्रस्ताव दूंगा कि मुझे वास्तव में कोई जानकारी नहीं है कि यह मेरे द्वारा किए जा रहे कार्यों को हासिल करने का सबसे अच्छा तरीका है और मैं बेहतर सुझावों के लिए बहुत खुला हूं।एक एंगुलरजेएस नियंत्रक को सुनिश्चित करना

मुझे OAUTH2 का उपयोग कर एक उपयोगकर्ता खाता प्रणाली मिली है जो मेरे डेटाबेस में उपयोगकर्ता की जानकारी देखता है और इसे एक चर के रूप में सहेजता है, $rootScope.userInfo। यह एक नियंत्रक में रहता है जो मेरे ऐप के body में जोड़ा गया है; यहां मैं सोच रहा था कि उच्चतम स्तर नियंत्रक उन लोगों के सामने लोड होगा जो इसके भीतर रहते हैं, लेकिन स्पष्ट रूप से नहीं।

अगर मैं एक दृश्य जो मेरे mainCtrl से पहले इस $rootScope.userInfo वस्तु का उपयोग करने के लिए अपने डेटाबेस से उस में लोड करने के लिए का अवसर मिल सके कोशिश करता है लोड, यह एक जावास्क्रिप्ट त्रुटि और Angular टूट जाता है फेंकता है।

<body ng-controller="mainCtrl"> 
    <header>Content</header> 
    <div class='main-view' ng-controller="userProfile"> 
     <p>{{user.name}}</p> 
     <p>{{user.email}}</p> 
    </div> 
</body> 
इस तरह

mainCtrl में मैं $rootScope.userInfo लोड हो रहा है::

संदर्भ के लिए, टेम्पलेट का मोटा अनुमान है

$http.get('/api/users/' + $cookies.id). 
    success(function(data) { 
     $rootScope.userInfo = data.user[0]; 
     console.log("User info is:"); 
     console.log($rootScope.userInfo); 
     $scope.status = 'ready'; 
    }); 
तब मेरे userProfile नियंत्रण के लिए

, मुझे क्या करना:

function userProfile($scope, $cookies, $http, $routeParams, $rootScope){ 
    if($scope.status == 'ready'){ 
    $scope.user = $rootScope.userInfo; 
    console.log("Double checking user info, here it is:"); 
    console.log($rootScope.userInfo); 
    } 
} 

यदि मैं ऐप में किसी दूसरे पृष्ठ से आ रहा हूं ich $rootScope.userInfo पर कॉल नहीं करता है, एपीआई के पास इसे देखने के लिए पर्याप्त समय है और मेरा userProfile पृष्ठ ठीक काम करता है। हालांकि अगर एक पूर्ण पृष्ठ रीफ्रेश कर रहे हैं, तो $rootScope.userInfo में लोड करने का समय नहीं है और मुझे त्रुटियां मिलती हैं।

मैं इसे कैसे ठीक कर सकता हूं?

उत्तर

14

आपके द्वारा वर्णित समस्या $rootScope का उपयोग कर नियंत्रकों के बीच डेटा साझा करने की अनुशंसा नहीं की जाने वाली कारणों में से एक है: यह दो नियंत्रकों के बीच एक मैनुअल "अदृश्य" निर्भरता बनाता है, जिसे अंतिम उपयोगकर्ता को मैन्युअल रूप से ठीक करने के बाद मैन्युअल रूप से ठीक करना होगा अभी तक अन्य नियंत्रक।

अनुशंसित समाधान उपयोगकर्ता लोडिंग तर्क को एक सेवा में स्थानांतरित करने के लिए है, userProfileService कहें, जिसे आप दोनों नियंत्रकों में इंजेक्ट करते हैं। फिर इसे एक बार बनाया जाएगा, और दोनों नियंत्रकों के लिए उपयोग किया जाएगा। ऐसी सेवा में आप $http के साथ उपयोगकर्ता प्रोफ़ाइल लोड कर सकते हैं जब नियंत्रक इसके लिए पूछता है, और अगली बार कैश से इसे वापस कर देता है। इस तरह, एक नियंत्रक से दूसरे नियंत्रक की बजाय निर्भरता दोनों नियंत्रकों से साझा सेवा तक जाती है।

मैं AngularJS दस्तावेज़ का एक बड़ा प्रशंसक नहीं हूं, लेकिन इससे मदद मिल सकती है: DI, Creating Services, और Injecting Services

+0

यह बहुत करीब है, मुझे इसे सेवा के रूप में उपयोग करने का विचार पसंद है। हालांकि यह लोडिंग-ऑर्डर समस्या को हल नहीं करता है। मेरे पास सेवा स्थापित है, लेकिन सेवा ने किसी भी डेटा को वापस करने से पहले यह अभी भी नियंत्रक को लोड करता है! विचार? – Jascination

+0

मैंने यहां एक अद्यतन प्रश्न बना दिया है: http://stackoverflow.com/questions/18477711/force-angularjs-service-to-return-data-before-loading-controller मैं इसे उत्तर के रूप में स्वीकार करूंगा जैसा यह करता है अधिकांश नौकरी, लेकिन उसको भी जवाब देने में संकोच न करें। – Jascination

0

उपयोग सफलता के बजाय then और ng-include का उपयोग कर बच्चे नियंत्रक की लोडिंग देरी:

<div class='main-view' ng-controller="userProfile"> 
    <p>{{user.name}}</p> 
    <p>{{user.email}}</p> 
</div> 

mainCtrl अंदर कॉलबैक::

<body ng-controller="mainCtrl"> 
    <header>Content</header> 
    <ng-include src="templatePath"></ng-include>   
</body> 

एक नया खाका userprofile.html अंदर एचटीएमएल ले जाएँ

$http.get('/api/users/' + $cookies.id). 
    then(function(data) { 
     /* mainCtrl being the parent controller, simply exposing the 
      properties to $scope would make them available 
      to all the child controllers.*/ 
     $rootScope.userInfo = data.user[0]; 
     /* assign the template path to load the template and 
      instantiate the controller */ 
     $scope.templatePath = "userprofile.html"; 
    }); 
+0

'$ http.success (foo)' 'http.then (foo)' का उपनाम है जो सभी तर्कों को सही ढंग से पास करता है।'सफलता' को 'फिर' हल करने के लिए क्या बदल जाएगा? [स्रोत] देखें (https://github.com/angular/angular.js/blob/master/src/ng/http.js#L673)। –

+0

@stevuu हाँ। ऐसा लगता है कि एक दूसरे का उपयोग करने में कोई बात नहीं है। – AlwaysALearner

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