1

I've been facing an unexpected issue. Here is my code

<li ng-repeat="(key,product) in products">
   <div class="avl-box">
     <a href="javascript:void();" ng-click="showDetail(product.item_id);">
         <img ng-src="{{SITEURL}}files/item/f_image/{{key}}/{{product.f_image}}" width="1000" height="1000" alt="">
     </a>
   </div>
</li>

In my products array, I've 3 products. All things are working fine even ng:click(); too. But my issue is why ng:click executes three times when I click once ? I've searched it a lot but nothing works for me. The same issue I'd with ng-options and ng-change together. See below example -

<select class="form-control dropDownPercent" name="demo" ng-model="CampaignsService.percentModel[$index]" ng-change="CampaignsService.showChange(CampaignsService.percentModel[$index], $index)" ng-options="o as o for o in CampaignsService.percentDropDownOptions[$index].values">

Options were coming properly, in this drop down I'd 10 items to display, but when I chose one then showChange function did execute 10 times. Can anyone help me?

1
  • 1
    can you create a fiddle/plnkr that reproduces the problem? Commented Jun 10, 2015 at 7:57

2 Answers 2

1

I found a reason behind the failure of my code after a long walk. The reason was, I was calling a function in one of my expression and that was

<div class="slide3-price"> {{showDetail().item_price | currency}} </div>

and my function was

$scope.showDetail = function (prod_id) {

            if (typeof prod_id === 'undefined') {
                prod_id = 27;
            }
            //logical code
            return {
                'colors': json.campaign_data.Product[prod_id].Color,
                'prod_title': this.val,
                'f_image': json.campaign_data.Product[prod_id].f_image,
                'item_id': prod_id,
                'item_price': json.campaign_data.Product[prod_id].price
            }

        }

So binding a function in expression forces that function to be reevaluated for the every item on every digest. Instead of calling a function in an expression, I created an array of values and use them in template. Like

<div class="slide3-price"> {{campaignDetailDescription['item_price'] | currency}} | currency}} </div>

But to prevent multiple times calling a function we need to add a watch listener to this variable or add a counter vairable. I made a counter and now my function looks like

$scope.showDetail = function (prod_id) {

            var counter = 0;

            if (counter === 0) {

                if (typeof prod_id === 'undefined') {
                    $scope.setItemId();
                } else {
                    $scope.item_id2 = prod_id;
                }

                $scope.gettitle($scope.item_id2);

                $scope.campaignDetailDescription['colors'] = $scope.json.campaign_data.Product[$scope.item_id2].Color;
                $scope.campaignDetailDescription['prod_title'] = $scope.val;
                $scope.campaignDetailDescription['f_image'] = $scope.json.campaign_data.Product[$scope.item_id2].f_image;
                $scope.campaignDetailDescription['item_id'] = $scope.item_id2;
                $scope.campaignDetailDescription['item_price'] = $scope.json.campaign_data.Product[$scope.item_id2].price;

            }
            counter++;
        }

Now my function is executing only once for ng-click. Thanks to SO.

Sign up to request clarification or add additional context in comments.

Comments

0

The classic Javascript way to avoid multiple click events being fired is to wrap your code in a timeout. The angular version of this, is:

var timer;
function showDetail() {
  if (timer) {
      $timeout.cancel(timer);
  }
  timer = $timeout(function() {
      // your code
  }, 1000);
}

If a second onClick event is fired within a second, it will be cancelled.

Although, it would be useful if we could see a plunkr, as the behaviour you are describing is not normal. Use the above code as a last resort, only.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.