2016-04-29 11 views
5

का अजीब व्यवहार आज मुझे अंगुलरजेएस में $ घड़ी का उपयोग करके कुछ वास्तव में अजीब व्यवहार का सामना करना पड़ता है।

https://jsfiddle.net/yLeLuard/

यह उदाहरण एक सेवा है जो एक state चर का ट्रैक रखेगा शामिल हैं: मैं निम्न उदाहरण के लिए अपने कोड को सरल बनाया। निर्देशों का उपयोग डीओएम को सेवा के माध्यम से state परिवर्तनीय को बदलने के लिए एक क्लिक ईवेंट को बाध्य करने के लिए किया जाता है।

वहाँ इस उदाहरण में दो समस्याएं हैं: (इस पर एनजी-क्लिक करें संपत्ति के साथ)

  1. पहले बंद करें बटन केवल ng- बिना
  2. दो बटन दूसरे क्लिक पर राज्य में परिवर्तन क्लिक सब

main.html

<div ng-controller="main"> 
    State: {{ api.isOpen | json }} 
    <div ng-click="" open> 
    <button>Open - Working fine</button> 
    </div> 
    <div ng-click="" close> 
    <button>Close - Works, but only on second click</button> 
    </div> 
    <div open> 
    <button>Open - Not Working</button> 
    </div> 
    <div close> 
    <button>Close - Not Working</button> 
    </div> 
</div> 
पर राज्य नहीं बदल रहे हैं

main.js

var myApp = angular.module('myApp', []); 

myApp.controller('main', ['$scope', 'state', function($scope, state) { 
    $scope.api = state; 

    $scope.api.isOpen = false; 

    $scope.$watch('api.isOpen', function() { 
    console.log('state has changed'); 
    }); 
}]); 

myApp.directive('open', ['state', function(state) { 
    return { 
    restrict: 'A', 
    scope: {}, 
    replace: true, 
    template: '<button>Open</button>', 
    link: function(scope, element) { 
     element.on('click', function() { 
     state.isOpen = true; 
     }); 
    } 
    }; 
}]); 


myApp.directive('close', ['state', function(state) { 
    return { 
    restrict: 'A', 
    scope: {}, 
    replace: true, 
    template: '<button>Close</button>', 
    link: function(scope, element) { 
     element.on('click', function() { 
     state.isOpen = false; 
     }); 
    } 
    }; 
}]); 

myApp.service('state', function() { 
    return { 
    isOpen: null 
    }; 
}); 
+2

आप अपने निर्देशों को कैसे खोलते हैं और बंद करते हैं और इसके बजाय 'ng-click = "api.isOpen = true" 'और' ng-click = "api.isOpen = false" का उपयोग करते हैं। 'क्लिक' ईवेंट – floribon

+0

@floribon को बाध्य करने के बजाय देशी निर्देशों का उपयोग करना बेहतर है, मेरे असली निर्देशों में बहुत अधिक कार्यक्षमता है, इसलिए मैं एनजी-क्लिक का उपयोग नहीं कर सकता। इसके अलावा, मैं वास्तव में जानना चाहता हूं कि यह ठीक से क्यों काम नहीं कर रहा है। – Pascal

+0

मैं देखता हूं। फिर 'ng-click' को हटाएं और केवल अपना निर्देश रखें। क्या हो रहा था कि 'एनजी-क्लिक' एक स्कोप डाइजेस्ट को ट्रिगर कर रहा था, इसलिए यह काम करने वाला प्रतीत होता था लेकिन अविश्वसनीय – floribon

उत्तर

4

ऐसा इसलिए है क्योंकि आप click पर एक देशी घटना श्रोता का उपयोग कर रहे है। यह घटना एसिंक्रोनस और कोणीय पाचन चक्र से बाहर है, इसलिए आपको दायरे को मैन्युअल रूप से पचाने की आवश्यकता है।

myApp.directive('open', ['state', function(state) { 
    return { 
    restrict: 'A', 
    scope: {}, 
    link: function(scope, element) { 
     element.on('click', function() { 
     scope.$apply(function() { 
      state.isOpen = true; 
     }); 
     }); 
    } 
    }; 
}]); 

फिक्स्ड बेला: https://jsfiddle.net/7h95ct1y/

मैं सीधे राज्य को बदलने में सुझाव है एनजी-क्लिक करें: ng-click="api.isOpen = true"

+0

ऐसा लगता है कि यह सही जवाब है! बहुत बहुत धन्यवाद। यहां आपके समाधान का उपयोग करके मेरी समस्या का एक कार्य उदाहरण है: https://jsfiddle.net/yLeLuard/2/ – Pascal

0

आप एक पूर्व लिंक समारोह के रूप में अपने लिंक समारोह रखना चाहिए, इस समस्या का हल दूसरे क्लिक का।

https://jsfiddle.net/2c9pv4xm/

myApp.directive('close', ['state', function(state) { 
    return { 
    restrict: 'A', 
    scope: {}, 
    link:{ 
    pre: function(scope, element) { 
     element.on('click', function() { 
     state.isOpen = false; 
     console.log('click', state); 
     }); 
    } 
    } 
    }; 
}]); 

काम नहीं कर भाग के लिए के रूप में, आप div पर अपने निर्देश डाल रहे हैं, इसलिए जब आप div पर क्लिक करें यह काम करता है लेकिन बटन पर नहीं। आपका खुला निर्देश बटन पर होना चाहिए।

संपादित करें: अन्य टिप्पणीकारों ने सुझाव दिया कि आप सीधे एनजी-क्लिक में राज्य को बदल दें। मैं इसकी अनुशंसा नहीं करता, यह इस मामले में काम कर सकता है लेकिन यदि आपके पास ऐसा करने के लिए असाइनमेंट से अधिक होना चाहिए तो यह व्यवहार्य नहीं है।

+0

इस तरह? https://jsfiddle.net/2c9pv4xm/1/ मुझे सेवा अद्यतन नहीं दिख रहा है। – Pascal

+0

मेरी गलती। मैंने आपका कोड बहुत जल्दी पढ़ा।लिंक को पूर्व कार्यों के रूप में रखना, हालांकि कुछ कारणों से एनजी-क्लिक की उपस्थिति अनिवार्य प्रतीत होती है। संपादित करें: हालांकि दायरे का उपयोग करना। $ आवेदन वास्तव में अनुशंसित नहीं है, यह एक नए पाचन चक्र को मजबूर करता है और यदि आपके ऐप में बहुत से दर्शक हैं तो यह पूरे पृष्ठ की पाचन को धीमा कर सकता है। यदि आप केवल एनजी-क्लिक का उपयोग कर रहे हैं तो मैं इसे एक फ़ंक्शन में रखूंगा। – Seedy

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