javascript - AngularJS के साथ एक ही तत्व पर ng-click और ng-dblclick को संभालना




angularjs-directive angularjs-ng-click (4)

आप सिर्फ अपना लिख ​​सकते हैं। मैंने एक नज़र लिया कि कैसे कोणीय क्लिक को संभाला है और इसे कोड के साथ संशोधित किया है जो मुझे यहां मिला: Jquery बाइंड डबल क्लिक और सिंगल क्लिक अलग से

<div sglclick="singleClick()" ng-dblClick="doubleClick()" style="height:200px;width:200px;background-color:black">


mainMod.controller('AppCntrl', ['$scope', function ($scope) {
    $scope.singleClick = function() {
      alert('Single Click');
    }
    $scope.doubleClick = function() {
      alert('Double Click');
    }
}])


mainMod.directive('sglclick', ['$parse', function($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attr) {
          var fn = $parse(attr['sglclick']);
          var delay = 300, clicks = 0, timer = null;
          element.on('click', function (event) {
            clicks++;  //count clicks
            if(clicks === 1) {
              timer = setTimeout(function() {
                scope.$apply(function () {
                    fn(scope, { $event: event });
                }); 
                clicks = 0;             //after action performed, reset counter
              }, delay);
              } else {
                clearTimeout(timer);    //prevent single-click action
                clicks = 0;             //after action performed, reset counter
              }
          });
        }
    };
}])

यहाँ एक उदाहरण है

Plunker

मैं AngularJS के साथ सिंगल और डबल-क्लिक इवेंट हैंडलिंग दोनों की तलाश कर रहा था, क्योंकि AngularJS हमेशा एनजी-क्लिक इवेंट को फायर करता है, भले ही हमारे तत्व के लिए एनजी-डब्लक्लिक निर्देश हो।

यहाँ समाधान चाहने वालों के लिए कुछ काम कोड है:

जे एस:

function MyController($scope) {

    var waitingForSecondClick = false;
    $scope.singleClickAction = function() {

        executingDoubleClick = false;
        if (waitingForSecondClick) {
            waitingForSecondClick = false;
            executingDoubleClick = true;
            return $scope.doubleClickAction();
        }
        waitingForSecondClick = true;

        setTimeout(function() {
            waitingForSecondClick = false;
            return singleClickOnlyAction();
        }, 250); // delay

        /*
         * Code executed with single AND double-click goes here.
         * ...
         */

        var singleClickOnlyAction = function() {
            if (executingDoubleClick) return;

            /*
             * Code executed ONLY with single-click goes here.
             * ...
             */

        }

    }

    $scope.doubleClickAction = function() {

        /*
         * Code executed ONLY with double-click goes here.
         * ...
         */

    };

}

HTML:

<div ng-controller="MyController">
    <a href="#" ng-click="singleClickAction()">CLICK</a>
</div>

तो मेरा सवाल है (जब से मैं एक एंगुलरजेएस नौसिखिया हूं): क्या कोई और अधिक अनुभवी व्यक्ति उन दोनों घटनाओं को संभालने के लिए कुछ अच्छा निर्देश लिख सकता है?

मेरी राय में सही तरीका यह होगा कि आप सिंगल-क्लिक-ओनली कोड को हैंडल करने के लिए एनजी-क्लिक, एनजी-डब्लक्लिक के व्यवहार को बदलें और कुछ "एनजी-सेलक्लिक" निर्देश जोड़ें। पता नहीं अगर यह संभव भी है, लेकिन मुझे यह सभी के लिए बहुत उपयोगी लगेगा।

अपनी राय साझा करने के लिए स्वतंत्र महसूस करें!


इस पार आया और सोचा कि मैं एक विकल्प निकालूंगा। यह मूल पोस्टर से दो प्रमुख बिंदुओं से अलग नहीं है।

1) कोई नेस्टेड फ़ंक्शन घोषणा नहीं है।

2) मैं $ टाइमआउट का उपयोग करता हूं। मैं अक्सर देरी के बिना भी $ टाइमआउट का उपयोग करता हूं ... खासकर अगर मैं अन्य काम करने के वादे को लात मार रहा हूं। $ 500 का समय पचाने के चक्र के दौरान आता है, जिससे यह सुनिश्चित हो जाता है कि कोई भी डेटा स्कोप लागू हो जाए।

दिया हुआ

<img src="myImage.jpg" ng-click="singleClick()" ng-dblclick="doubleClick()">

आपके कंट्रोलर में सिंगलक्लिक फंक्शन दिखेगा:

$scope.singleClick = function () {
    if ($scope.clicked) {
        $scope.cancelClick = true;
        return;
    }

    $scope.clicked = true;

    $timeout(function () {
        if ($scope.cancelClick) {
            $scope.cancelClick = false;
            $scope.clicked = false;
            return;
        }

        //do something with your single click here

        //clean up
        $scope.cancelClick = false;
        $scope.clicked = false;
    }, 500);
};

और DoubleClick फ़ंक्शन सामान्य दिखाई देगा:

$scope.doubleClick = function () {

    $timeout(function () {

        //do something with your double click here

    });
};

आशा है कि यह किसी की मदद करता है ...


ग्रेग का जवाब निश्चित रूप से सबसे साफ जवाब के करीब है। मैं एक ऐसे संस्करण के साथ आने के लिए उनके उत्तर पर निर्माण करने जा रहा हूं, जहां किसी नए कोड को लिखने की आवश्यकता नहीं है, और आपके नियंत्रक में किसी नए इंजेक्शन का उपयोग करने की आवश्यकता नहीं है।

पहली बात यह है कि इस प्रकार की समस्याओं के आसपास हैकआउट करने के लिए टाइमआउट का उपयोग क्यों किया जाता है। अनिवार्य रूप से, वे एक फ़ंक्शन बनाने के लिए उपयोग किए जाते हैं ताकि वर्तमान ईवेंट लूप के बाकी हिस्सों को छोड़ दें ताकि निष्पादन साफ ​​हो। कोणीय में, हालांकि, आप वास्तव में रुचि रखते हैं कि पाचन लूप कैसे काम करता है। यह आपके क्लासिक इवेंट हैंडलर के रूप में लगभग समान है, कुछ मामूली अंतरों को छोड़कर जो इसे UX के लिए महान बनाते हैं। फ़ंक्शन निष्पादन के आदेश के साथ गड़बड़ करने के लिए आपके पास कुछ उपकरण हैं scope.$eval , scope.$evalAsync , scope.$apply , और scope.$applyAsync

मेरा मानना ​​है कि $apply s एक और डाइजेस्ट लूप को बंद कर देगा, जो $eval s को छोड़ देता है। $eval मौजूदा $scope के संदर्भ में जो भी कोड आपको तुरंत शामिल करेगा और $evalAsync आपके कार्य को पचाने वाले लूप के अंत में चलाने के लिए कतार में $evalAsync । अनिवार्य रूप से, $evalAsync एक बड़े अंतर के साथ $timeout का क्लीनर संस्करण है - पहले का संदर्भ है और गुंजाइश पर मौजूद है!

इसका मतलब यह है कि आप वास्तव में, ng-click और ng-dblclick को एक ही तत्व पर संभाल ng-clickहालाँकि, ध्यान दें कि यह अभी भी डबल-क्लिक फ़ंक्शन से पहले सिंगल-क्लिक फ़ंक्शन को ट्रिगर करेगा । यह पर्याप्त होना चाहिए:

<div ng-controller="MyController">
    <a href="#"
       ng-click="$evalAsync(singleClickAction())"
       ng-dblclick="doubleClickAction()">
       CLICK
    </a>
</div>

यहां कोणीय 1.6.4 का उपयोग करते हुए इच्छित कार्यक्षमता के साथ एक jsfiddle है


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

उदाहरण

<div ng-click="singleClick()"><span double-click="doubleClick()">double click me</span></div>

कोड

.directive('doubleClick', function($timeout, _) {

  var CLICK_DELAY = 300
  var $ = angular.element

  return {
    priority: 1, // run before event directives
    restrict: 'A',
    link: function(scope, element, attrs) {
      var clickCount = 0
      var clickTimeout

      function doubleClick(e) {
        e.preventDefault()
        e.stopImmediatePropagation()
        $timeout.cancel(clickTimeout)
        clickCount = 0
        scope.$apply(function() { scope.$eval(attrs.doubleClick) })
      }

      function singleClick(clonedEvent) {
        clickCount = 0
        if (attrs.ngClick) scope.$apply(function() { scope.$eval(attrs.ngClick) })
        if (clonedEvent) element.trigger(clonedEvent)
      }

      function delaySingleClick(e) {
        var clonedEvent = $.Event('click', e)
        clonedEvent._delayedSingleClick = true
        e.preventDefault()
        e.stopImmediatePropagation()
        clickTimeout = $timeout(singleClick.bind(null, clonedEvent), CLICK_DELAY)
      }

      element.bind('click', function(e) {
        if (e._delayedSingleClick) return
        if (clickCount++) doubleClick(e)
        else delaySingleClick(e)
      })

    }
  }

})




angularjs-ng-click