2012-12-31 10 views
6

प्रस्तुत करने का कारण बनता है मैं नीचे एनजी-स्विच के साथ एनजी-स्विच का उपयोग करने की कोशिश कर रहा हूं। समस्या एनजी-इनिट के साथ है और पूरे नियंत्रक ब्लॉक को किसी भी एनजी-में परिवर्तन में पुनः प्रस्तुत किया जा रहा है।एनजी-शामिल नियंत्रक ब्लॉक को

login_form.html में, जब कोई उपयोगकर्ता लॉगिन करता है, तो मैं loginCtrl में isLoggedIn = true सेट करता हूं। हालांकि इससे नीचे पूर्ण एचटीएमएल का पुन: प्रस्तुत करने का कारण बनता है, जिससे एनजी-इनिट फिर से होता है।

मैं इस चक्र से कैसे बचूं?

<form class="form-inline"> 
    <input type="text" placeholder="Email" ng-model="userEmail" class="input-small"/> 
    <input type="password" placeholder="Password" ng-model="userPassword" class="input-small"/> 
    <button type="submit" ng-click="login(userEmail, userPassword)" class="btn">Sign In</button> 
</form> 

नीचे नियंत्रक है - -

 <div ng-controller="LoginCtrl" ng-init="isLoggedIn = false" class="span4 pull-right"> 
     <div ng-switch on="isLoggedIn"> 
      <div ng-switch-when="false" ng-include src="'login_form.html'"></div> 
      <div ng-switch-when="true" ng-include src="'profile_links.html'"></div> 
     </div> 
     </div> 

नीचे लॉगिन फार्म के लिए HTML है

angularApp.factory('currentUser', function($rootScope) { 
    // Service logic 
    // ... 
    // 
    var allUsers = {"[email protected]": {name: "Robert Patterson", role: "Admin", email: "[email protected]", password: "rob"}, 
      "[email protected]":{name: "Steve Sheldon", role: "User", email: "[email protected]", password: "steve"}} 

    var isUserLoggedIn = false; 

    // Public API here 
    return { 
    login: function(email, password){ 
     var user = allUsers[email]; 
     var storedPass = user.password; 

     if(storedPass === password){ 
     isUserLoggedIn = true; 
     return true; 
     } 
     else 
     { 
     return false; 
     } 
    }, 
    logout: function(){ 
     $rootScope.$broadcast('logout'); 
     isUserLoggedIn = false; 
    }, 

    isLoggedIn: function(){ 
     return isUserLoggedIn; 
    } 
}; 
}); 

उत्तर

38

मेरा मानना ​​है कि आपकी समस्या प्रोटोटाइप विरासत के तरीके का परिणाम है। एनजी-शामिल अपने बच्चे के दायरे बनाता है। एक बच्चे के दायरे में एक आदिम मूल्य को असाइन करना उस दायरे पर एक नई संपत्ति बनाता है जो मूल संपत्ति को छाया/छुपाता है।

मुझे लगता है कि login_form में।HTML आप निम्नलिखित की तरह कुछ करते हैं जब में एक उपयोगकर्ता के लॉग:

before assignment

isLoggedIn के बाद सही पर सेट किया जाता है:

<a ng-click="isLoggedIn=true">login</a> 

पहले isLoggedIn सही पर सेट है, यह क्या अपने कार्यक्षेत्र की तरह लग रही है

after assignment

उम्मीद है कि चित्रों यह स्पष्ट क्यों करते हैं:, यह क्या अपने कार्यक्षेत्र की तरह लग रही है यह आपको समस्याएं पैदा कर रहा है।

क्यों मूलरूप विरासत पुरातन के साथ इस तरह काम करता है के बारे में अधिक जानकारी के लिए कृपया What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

ऊपर लिंक बताया गया है, तीन समाधान है:

  1. अपने मॉडल के लिए माता-पिता में एक वस्तु को परिभाषित , उसके बाद बच्चे में उस ऑब्जेक्ट की एक संपत्ति का संदर्भ लें: parentObj.isLoggedIn
  2. login_form.html में $ parent.isLoggedIn का उपयोग करें - फिर यह एक नया निर्माण करने के बजाय, $ मूल दायरे में आदिम का संदर्भ देगा। उदा।
    <a ng-click="$parent.isLoggedIn=true">login</a>
  3. मूल दायरे पर एक फ़ंक्शन को परिभाषित करें, और इसे बच्चे से कॉल करें - उदाहरण के लिए, setIsLoggedIn()। यह सुनिश्चित करेगा कि अभिभावक स्कोप संपत्ति सेट की जा रही है, न कि बच्चे के दायरे की संपत्ति।

अद्यतन: अपने HTML की समीक्षा करने में, आप वास्तव में बच्चे को स्कोप के दो स्तर के बाद से एनजी स्विच और एनजी-शामिल प्रत्येक अपने स्वयं के स्कोप बनाने पड़ सकता है। इसलिए, चित्रों को पोते के दायरे की आवश्यकता होगी, लेकिन तीन समाधान समान हैं ... # 2 को छोड़कर, जहां आपको $ माता-पिता का उपयोग करने की आवश्यकता होगी। $ Parent.isLoggedIn - बदसूरत। तो मेरा सुझाव है विकल्प 1 या 3.

Update2: @ murtaza52 सवाल करने के लिए कुछ कोड जोड़ा ... अपने नियंत्रक से ng-init="isLoggedIn = false" निकालें (आपकी सेवा में अपनी isUserLoggedIn चर के माध्यम से लॉगिन राज्य प्रबंध कर रहा है) और loginStatus पर स्विच () आपके नियंत्रक में: <div ng-switch on="loginStatus()">

यहां एक है।

+0

मुझे लगता है कि मेरा जवाब समाधान 1 है? – asgoth

+0

@asgoth, ठीक है, आपका पहेली अनिवार्य रूप से समाधान 1 का उपयोग करता है, हालांकि अतिरिक्त नियंत्रकों के कारण अभी तक एक और बच्चा गुंजाइश है। आपका "एक नियंत्रक" उत्तर अनिवार्य रूप से समाधान 3 का उपयोग करता है - आप अभिभावक स्कोप संपत्ति को बदलने के लिए मूल दायरे में एक फ़ंक्शन को कॉल कर रहे हैं (जो प्रोटोटाइप विरासत के कारण बाल स्कॉप्स के लिए उपलब्ध है)। लेकिन तब वहां कुछ समाधान 1 है, मूल वस्तु संपत्ति के कारण - आप समाधान 3 के साथ एक आदिम का उपयोग कर सकते हैं। यहां एक [समाधान 3 के लिए पहेली] है (http://jsfiddle.net/mrajcok/jNxyE /) जो मूल दायरे में एक आदिम का उपयोग करता है। विस्तृत उत्तर मार्क के लिए –

+0

+1। मुझे अपने समाधान को लागू करने दें और देखें कि क्या यह समस्या का समाधान करता है। – murtaza52

3

मैंने -

angularApp.controller('LoginCtrl', function($scope, currentUser){ 

    $scope.loginStatus = function(){ 
    return currentUser.isLoggedIn(); 
    }; 

/* $scope.$on('login', function(event, args) { 
    $scope.userName = args.name; 
    }); 

    $scope.$on('logout', function(event, args) { 
    $scope.isLoggedIn = false; 
    });*/ 

    $scope.login = function(email, password){ 
    currentUser.login(email, password); 
    }; 

    $scope.logout = function(){ 
    currentUser.logout(); 
    }; 

}); 

ब्लो सेवा है working example है। चाल यह है कि स्कोप वैरिएबल का मूल्यांकन किया जाना एक वस्तु होना चाहिए, न कि एक प्राचीन प्रकार। ऐसा लगता है कि $scope.$watch() आदिम प्रकारों को ठीक से नहीं देख रहा है (जो एक बग है)। जेएसफ़िल्ड में दो बाल नियंत्रकों के साथ एक अभिभावक नियंत्रक है, लेकिन यह केवल एक (अभिभावक) नियंत्रक के साथ भी काम करेगा।

HTML:

<div ng-controller="LoginCheckCtrl"> 
     <div ng-switch on="user.login"> 
      <div ng-switch-when="false" ng-include="'login'"></div> 
      <div ng-switch-when="true" ng-include="'logout'"></div> 
     </div> 
</div> 

नियंत्रक:

function LoginCheckCtrl($scope) { 
    $scope.user = { 
     login: false 
    }; 
} 

नोट: यह भी केवल एक ही नियंत्रक के साथ काम करेंगे:

function LoginCheckCtrl($scope) { 
    $scope.user = { 
     login: false 
    }; 
    $scope.login = function() { 
     console.log($scope.user.login ? 'logged in' : 'not logged in'); 
     $scope.user.login = true; 
    }; 
    $scope.logout = function() { 
     console.log($scope.user.login ? 'logged in' : 'not logged in'); 
     $scope.user.login = false; 
    }; 
} 
+0

यह भी वही व्यवहार में परिणाम देता है। पुनः प्रतिपादन अभी भी चर को रीसेट करता है। पुन: प्रस्तुत करने या रीसेट करने के तरीके पर कोई विचार? – murtaza52

+0

बस देखा, मेरा jsfiddle एक अंतहीन पाश में चला गया :) – asgoth

+1

मेरा जवाब संपादित किया। लिंक में उदाहरण देखें। आपकी टिप्पणी के लिए – asgoth

0

आप उस राज्य को स्टोर कर सकते हैं जिसे माता-पिता के दायरे में नियंत्रक के पुनर्मूल्यांकन से बचने की आवश्यकता है। मुझे नहीं लगता कि $ rootScope पर भी लॉज किया गया है।

इसके अलावा, आप नियंत्रक के अंदर प्रारंभ कर सकते हैं, जो इस मामले में क्लीनर होगा (लेकिन यह आपकी समस्या का समाधान नहीं करता है)।

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