AngularJS ng-stop stopPropagation पर क्लिक करें


433

मेरे पास एक टेबल पंक्ति पर एक ईवेंट है और इस पंक्ति में एक क्लिक ईवेंट के साथ एक डिलीट बटन भी है। जब मैं डिलीट बटन पर क्लिक करता हूं तो पंक्ति पर क्लिक इवेंट भी निकाल दिया जाता है।

यहाँ मेरा कोड है।

<tbody>
  <tr ng-repeat="user in users" class="repeat-animation" ng-click="showUser(user, $index)">
    <td>{{user.firstname}}</td>
    <td>{{user.lastname}}</td>
    <td>{{user.email}}</td>
    <td><button class="btn red btn-sm" ng-click="deleteUser(user.id, $index)">Delete</button></td>
  </tr>
</tbody>

showUserटेबल सेल में डिलीट बटन पर क्लिक करने पर मैं कैसे रोक सकता हूँ कि ईवेंट को निकाल दिया गया है?

जवाबों:


801

ngClick निर्देश (और साथ ही अन्य सभी घटना निर्देश) $eventचर बनाता है जो समान दायरे पर उपलब्ध है। यह चर JS eventऑब्जेक्ट का संदर्भ है और इसका उपयोग कॉल करने के लिए किया जा सकता है stopPropagation():

<table>
  <tr ng-repeat="user in users" ng-click="showUser(user)">
    <td>{{user.firstname}}</td>
    <td>{{user.lastname}}</td>
    <td>
      <button class="btn" ng-click="deleteUser(user.id, $index); $event.stopPropagation();">
        Delete
      </button>
    </td>              
  </tr>
</table>

PLUNKER


2
अगर यह कंट्रोलर कोड - $ स्कोप में उपलब्ध है तो मैं इसका पता नहीं लगा सकता। $ ईवेंट काम नहीं करता था। कोई विचार?
user1338062

93
@event ऑब्जेक्ट ng-click निर्देश के अंदर बनाया गया है, और यह आपके ng-clickहैंडलर फ़ंक्शन पर इसे पास करने के लिए उपलब्ध है ng-click="deleteUser(user.id, $event)":।
स्टीवे

6
धन्यवाद, कि एक तरह लगा, लेकिन मुझे लगता है कि यह अभी भी बदबू आ रही है :)
user1338062

2
मुझे लगता है कि यह इस तरह के कई भावों को निष्पादित करने के लिए एक एंटीपैटर्न है। डिलीटयूसर () और फिर स्टॉपप्रोपेगैनेशन () उस फंक्शन के अंदर तीसरे तर्क के रूप में $ घटना को क्यों नहीं पारित किया गया?
djheru

18
मुझे $event.preventDefault()भी जोड़ना था, अन्यथा $event.stopPropagation()बटन पर क्लिक करने पर कॉलिंग मुझे मेरे ऐप के रूट पर रीडायरेक्ट कर रही थी।
डेस्टीनी

124

स्टीवी के जवाब के अलावा। मामले में जब आपका कॉलबैक यह तय करता है कि प्रचार बंद किया जाना चाहिए या नहीं, तो मैंने कॉल करने के लिए $eventऑब्जेक्ट पास करना उपयोगी पाया :

<div ng-click="parentHandler($event)">
  <div ng-click="childHandler($event)">
  </div>
</div>

और फिर कॉलबैक में ही, आप यह तय कर सकते हैं कि क्या घटना का प्रचार रोका जाना चाहिए:

$scope.childHandler = function ($event) {
  if (wanna_stop_it()) {
    $event.stopPropagation();
  }
  ...
};

10
यह html विशेषता में कई अभिव्यक्तियों को निष्पादित करने से अधिक सुरुचिपूर्ण है, धन्यवाद
ईजीऑन

3
HTML एनजी-क्लिक निर्देश में '$ घटना' तर्क रखना याद रखें। मैं पहली बार में उस पर ठोकर खाई।
थिंकबोनोबो

1
तत्काल रोक बेहतर उपयोग के लिए $ event.stopImmediatePropagation ()
Edgar Chavolla

इतना सरल, फिर भी इतना अनदेखा। मैं चुने हुए जवाब और सोच को देख रहा था "वास्तव में! यह बदसूरत है?"। इसे एक पैरामीटर के रूप में पारित करने का एहसास भी नहीं था। बहुत अच्छे।
tfrascaroli

10

मैंने एक निर्देश लिखा, जो आपको उन क्षेत्रों को सीमित करने देता है जहां एक क्लिक का प्रभाव पड़ता है। यह इस तरह के कुछ परिदृश्यों के लिए इस्तेमाल किया जा सकता है, इसलिए मामले के आधार पर एक मामले पर क्लिक से निपटने के बजाय आप बस यह कह सकते हैं कि "क्लिक इस तत्व से बाहर नहीं आएंगे"।

आप इसे इस तरह उपयोग करेंगे:

<table>
  <tr ng-repeat="user in users" ng-click="showUser(user)">
    <td>{{user.firstname}}</td>
    <td>{{user.lastname}}</td>
    <td isolate-click>
      <button class="btn" ng-click="deleteUser(user.id, $index);">
        Delete
      </button>
    </td>              
  </tr>
</table>

ध्यान रखें कि यह अंतिम सेल के सभी क्लिकों को रोकेगा, न कि केवल बटन को। यदि आप ऐसा नहीं चाहते हैं तो आप इस तरह से बटन को लपेटना चाहते हैं:

<span isolate-click>
    <button class="btn" ng-click="deleteUser(user.id, $index);">
        Delete
    </button>
</span>

यहाँ निर्देश का कोड है:

angular.module('awesome', []).directive('isolateClick', function() {
    return {
        link: function(scope, elem) {
            elem.on('click', function(e){
                e.stopPropagation();
            });
        }
   };
});

अच्छा! मैंने आपके निर्देश का नाम बदल दिया है ngClick, क्योंकि मैं वास्तव में कभी भी पहले से संभाले हुए कार्यक्रम का प्रचार नहीं करना चाहता।
माॅर्टिनस

1
उससे सावधान रहें। कुछ अन्य प्लगइन्स वास्तव में उन क्लिक्स को सुनना चाहते हैं। यदि आप टूलटिप्स का उपयोग करते हैं जो बाहर क्लिक करते समय बंद हो जाते हैं तो वे कभी भी बंद नहीं हो सकते हैं, क्योंकि बाहर के क्लिकों को शरीर में प्रचारित नहीं किया जा रहा है।
जेन्स

यह एक अच्छा बिंदु है, लेकिन यह समस्या आपके निर्देश के साथ भी होगी। हो सकता है कि मुझे ignoreNgClick=trueघटना की तरह ही एक संपत्ति जोड़ना चाहिए और इसे संभालना चाहिए ... किसी तरह। आदर्श रूप में, मूल ngClickनिर्देश में, लेकिन इसे संशोधित करने से यह गंदा लगता है।
महाआरती

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

1

इस मामले में कि आप मेरे जैसे एक निर्देश का उपयोग कर रहे हैं, यह इस तरह से काम करता है जब आपको किसी मॉडल या संग्रह में एक विशेषता को अपडेट करने के बाद उदाहरण के लिए दो डेटा बाइंडिंग बाइंडिंग की आवश्यकता होती है:

angular.module('yourApp').directive('setSurveyInEditionMode', setSurveyInEditionMode)

function setSurveyInEditionMode() {
  return {
    restrict: 'A',
    link: function(scope, element, $attributes) {
      element.on('click', function(event){
        event.stopPropagation();
        // In order to work with stopPropagation and two data way binding
        // if you don't use scope.$apply in my case the model is not updated in the view when I click on the element that has my directive
        scope.$apply(function () {
          scope.mySurvey.inEditionMode = true;
          console.log('inside the directive')
        });
      });
    }
  }
}

अब, आप इसे किसी भी बटन, लिंक, div, आदि में आसानी से उपयोग कर सकते हैं:

<button set-survey-in-edition-mode >Edit survey</button>

-14
<ul class="col col-double clearfix">
 <li class="col__item" ng-repeat="location in searchLocations">
   <label>
    <input type="checkbox" ng-click="onLocationSelectionClicked($event)" checklist-model="selectedAuctions.locations" checklist-value="location.code" checklist-change="auctionSelectionChanged()" id="{{location.code}}"> {{location.displayName}}
   </label>



$scope.onLocationSelectionClicked = function($event) {
      if($scope.limitSelectionCountTo &&         $scope.selectedAuctions.locations.length == $scope.limitSelectionCountTo) {
         $event.currentTarget.checked=false;
      }
   };


7
क्या आप कुछ स्पष्टीकरण जोड़ेंगे कि आपको क्यों लगता है कि यह प्रश्न का उत्तर देता है?
paisanco

यह प्रश्न का उत्तर देता है। यह दिखाता है कि घटना को कॉलबैक में कैसे पास किया जाए जो प्रारंभिक प्रश्न से अधिक है।
हेवस्टोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.