2016-02-25 7 views
8

मेरे पास एक AngularJS 1.4 * एप्लिकेशन स्थानीय रूप से चल रहा है (अभी तक)। इस ऐप को लैरावेल 5.1 बैकएंड रीस्टफुल एपीआई द्वारा परोसा जाता है।मेरे दर्शक को एक ही बदलाव पर दो बार क्यों बुलाया जाता है?

मुझे यह ऐप बनाना है जो पैकेज यात्रा का प्रतिनिधित्व करता है। एक पैकेज दिन से बना है, 0 से एन दिनों तक। प्रत्येक दिन 0 से एन सेवाओं तक की सेवाओं की एक सूची होती है। और एक होटल।

मेरा वेब सर्वर, जिसमें से मेरा लार्वाल एप्लिकेशन खपत करता है, मुझे एक पूर्व निर्धारित पैकेज प्रदान करता है, जिसमें दिन की एक सूची होती है: प्रत्येक व्यक्ति सेवाओं की एक सूची और एक होटल डेटा (अब तक अप्रयुक्त)। प्रतिक्रिया पर मेरे पास पैकेज के लिए गुणों की एक सूची है (जो अब के लिए कोई फर्क नहीं पड़ता) और days_info नामक दिनों की एक सरणी है। यह प्रतिक्रिया पर $scope.package में रखी जा रही है। पैकेज नियंत्रकpackageBlock नामक निर्देश भी घोषित करता है, जिसमें दिनों की सूची और पैकेज के लिए कुछ अन्य डेटा शामिल है।

<div ng-repeat="day in package.days_info" class='row'> 
    <div class='col-md-12'> 
     <package-days-block></package-days-block> 
    </div> 
</div> 

<package-days-block> निर्देश के अंदर, मैं हर दिन के अंदर सेवाओं की सूची के माध्यम से पुनरावृति करने के लिए एक और है।

<div class='container-fluid' ng-repeat='service in day.services' ng-controller="ServiceController"> 
    <service-block></service-block> 
</div> 

वहीं समस्या शुरू होता है है: मेरी undestandment लिए, मैं अब एक $scope.service मेरी ServiceController अंदर है। इसलिए, मैंने इसे ServiceController के अंदर $scope.service के माध्यम से अपनी आवश्यकता पर बदलना शुरू कर दिया।

$ scope.service में service_id नामक एक विशेषता है। मैं इस पर एक श्रोता/द्रष्टा शब्दों में कहें, तो किसी भी समय $ scope.service.service_id में बदल गया है, मैं एक और service_table के लिए पूछना (सेवाओं के बारे में जानकारियां रखती है, यह service_id पहले से चुना या उपयोगकर्ता द्वारा बदला पर आधारित है), और इसे $scope.service.table में डाल दें।

// ServiceController 
$scope.reloadServicesTable = function(service_id, service_day, date, paxes){ 
    MandatoryService.getServiceTable(service_id, service_day, date, paxes) 
    .then(
     function(service_data) { 
      $scope.service.table = service_data; 
     }, 
     ... 
    ); 

reloadServicesTableservice_id परिवर्तन के लिए द्रष्टा पर कहा जाता है।

// ServiceController 
$scope.$watch(
    'service.service_id', // Places the watcher to watch the changes on the service's ID. 
    function(new_service, old_service) { 
     if(new_service === old_service) 
      return; 

     $scope.reloadServicesTable($scope.service.service_id, $scope.service.service_day, $scope.day.date, $scope.package.paxes); 

    } 
); 

समस्या यहाँ शुरू होता है: सेवा की मेज के लिए अनुरोध दो बार कहा जाता है जब service_id केवल एक बार बदल जाता है।

क्यों, भगवान, क्यों ?! service.table.price:

मेरी कोड है, जहां मैं, PackageController से, पूरे days_info सरणी के माध्यम से चलाने के लिए और एक विशेषता price service.table अंदर का मूल्य पढ़ता का एक और हिस्सा नहीं है। वहाँ में, मुझे पता है कि वहाँ दो गुंजाइश की: एक मैं से निपटने और अन्य है कि मैं कोई गुस्सा आईडिया कहाँ से आया है!

अगर मैं विधि है कि days_info के माध्यम से चलाता है के अंदर एक console.log($scope); शब्दों में कहें, मैं हर अनुरोध के लिए दो स्कोप मिलता है। इस विधि PackageController पर है।

कोई भी विचार क्यों यह हो रहा है?

पुनश्च: यह मेरा बहुत पहले AngularJS आवेदन है, तो, आराम से, अगर मैंने कुछ बुनियादी पर में गड़बड़ ...

संपादित करें:

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

मैं क्रोम कंसोल से कुछ स्क्रीन शॉट्स ले लिया:

पहले, requestions service_id

Request log for the service change (ordered by path name)

के परिवर्तन पर गोली चलाई जैसा कि आप देख सकते हैं, हर अनुरोध को हर बार दो बार बुलाया जाता है। यह एक बार की बात नहीं है। /api/service/{id}... सेवा की तालिका जानकारी के लिए कॉल है। /api/service/by_route/origin/... एक शहर से दूसरे शहर में सेवाओं की एक सूची देता है (या वही)। एक दूसरे पर हस्तक्षेप नहीं करता है।

अन्य छवि कंसोल.लॉग से पैकेजकंट्रोलर $ स्कोप से आउटपुट है, उस समय सेवा_आईडी बदल रही है।

Scopes for the PackageController

आप देख सकते हैं, वहाँ दो अलग-अलग दायरों है। और b गुंजाइश r गुंजाइश का बेटा है। r गुंजाइश भी service_id पर वॉचर को कॉल कर रहा है?

रकम कीमत के लिए कॉल differente स्थानों से दो बार बुलाया गया है, जैसा कि आप नीचे चित्र में देख सकते हैं:

Call Stack for the sumPrices method on PackageController

+3

आपका प्रश्न बहुत लंबा है और इसमें बहुत सारी अप्रासंगिक जानकारी है, लेकिन एक पुन: उत्पन्न परीक्षण मामले की कमी है। तो यह समझना मुश्किल है कि वास्तव में समस्या क्या है। लेकिन दस्तावेज कहता है: * [...] दुर्लभ मामलों में, यह अवांछनीय है क्योंकि श्रोता को तब देखा जाता है जब watchExpression का नतीजा नहीं बदला जाता है। श्रोता fn के भीतर इस परिदृश्य का पता लगाने के लिए, आप newVal और oldVal की तुलना कर सकते हैं। यदि ये दो मान समान हैं (===) तो श्रोता को प्रारंभिकरण के कारण बुलाया गया था। –

+5

आमतौर पर, घड़ी का उपयोग करना एक बुरा विचार है। यदि आपने हमें बताया, सरल तरीके से, आप जो हासिल करना चाहते हैं, हम आपको बेहतर तरीके से ढूंढने में मदद कर सकते हैं। –

+0

मैं तुलनात्मक फ़ंक्शन के बाद बुलाए गए एफएन में दो मानों (newValue और oldValue) की तुलना कर रहा हूं। यह समस्या नहीं है (अब)। चूंकि समारोह को व्यवस्थित रूप से दो बार बुलाया गया है! मैं अपने अनुरोध नेटवर्क लॉग से दो प्रिंट रखूंगा और सेवा के परिवर्तन पर अनुरोध के लिए एक दायरा रखूंगा। –

उत्तर

3

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

  1. मेरे लिए कारण यह है कि, नियंत्रक फिर से प्रारंभ हो रही किया गया था और एक अलग API कॉल कि में लिखा है, जो शुरू में पृष्ठ लोड करने का इरादा था वहाँ था।

  2. एक परिदृश्य भी हो सकता है जहां आपने मार्क अप में दो बार नियंत्रक असाइन किया है।

+0

यह सटीक था कि मेरे साथ क्या हुआ! आपको 14 सेकेंड की तरह बक्षीस नहीं मिला। =/पहले ही रॉबर्ट को सौंपा गया था।मैं एक div के लिए एक 'एनजी नियंत्रक' घोषित किया गया था और उसी नियंत्रक पर निर्देश बुला रहा था, इस प्रकार, इसे दो बार तत्काल! यही मुद्दा था। –

1
<div ng-repeat="day in package.days_info" class='row'> 
    <div class='col-md-12'> 
     <package-days-block day="day"></package-days-block> 
    </div> 
</div> 

<div class='container-fluid' ng-repeat='service in day.services'> 
    <service-block service="service"></service-block> 
</div> 

पास day और service नीचे निर्देशों में। Package.days_info पर वापस अपने day और service परिवर्तनों को पारित करने के लिए बाध्यकारी दो तरीकों का उपयोग करें।

अपने ServiceController को हटाएं यह नियंत्रक को दोहराने के लिए बहुत अधिक समझ में नहीं आता है। <service-block> और <package-days-block> ई निर्देश हैं जो तर्क को संभालते हैं।

लिखें केवल एक ही अपने PackageController में द्रष्टा कि package.days_info घड़ी जब आपके day या service परिवर्तन, यह बस यह पता लगाने और इसके बारे में कुछ कर सकते हैं।

बस चिल करें और इसे ठीक करें।

+0

समस्या बिल्कुल ठीक नहीं थी। लेकिन, टिप अच्छा था! बहुत अच्छा। चूंकि मैं शायद इसे अब से उपयोग करूँगा, इसलिए मैं आपको बक्षीस दूंगा (और यह 22 मिनट में भी समाप्त हो जाता है)। बहुत बहुत धन्यवाद। –

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