admin管理员组

文章数量:1425221

I've an issue with multiple ajax requests. For example I've a form with a button, and onclick it runs a service which essentially load list of items in a table; for now it should load a single item into a table when I hit the button.

However, when I hit the button multiple times, the same item is duplicated when its loaded.

How can I prevent while there is still no callback from the first one?

current ng service

var getItems = function () {

    var def = $q.defer();

    Items.get().then(function (items) {
       def.resolve(items);
    }, function (err) {
       ...
    });
};

Not sure if this is a solution, but when I write above code like this:

var def = false;
var getItems = function () {

    def = $q.defer();

    Items.get().then(function (items) {
       def.resolve(items);
    }, function (err) {
       ...
    });
};

This stops the duplication when I initialize the def = false, not sure if this is the correct approach by resetting the previous/old request to false?

I've an issue with multiple ajax requests. For example I've a form with a button, and onclick it runs a service which essentially load list of items in a table; for now it should load a single item into a table when I hit the button.

However, when I hit the button multiple times, the same item is duplicated when its loaded.

How can I prevent while there is still no callback from the first one?

current ng service

var getItems = function () {

    var def = $q.defer();

    Items.get().then(function (items) {
       def.resolve(items);
    }, function (err) {
       ...
    });
};

Not sure if this is a solution, but when I write above code like this:

var def = false;
var getItems = function () {

    def = $q.defer();

    Items.get().then(function (items) {
       def.resolve(items);
    }, function (err) {
       ...
    });
};

This stops the duplication when I initialize the def = false, not sure if this is the correct approach by resetting the previous/old request to false?

Share Improve this question asked Dec 29, 2014 at 16:03 Simple-SolutionSimple-Solution 4,29912 gold badges50 silver badges66 bronze badges 2
  • This seems like more of a logic issue than duplicated ajax requests... How does sending this request multiple times result in the same item being inserted into the collection multiple times? shouldn't the collection simply be set to the result, making it impossible to contain duplicates? Why are you appending the result to the collection? – Kevin B Commented Dec 29, 2014 at 16:22
  • Don't know, you didn't provide that code in your question. – Kevin B Commented Dec 30, 2014 at 14:42
Add a ment  | 

3 Answers 3

Reset to default 3

You can put a lock on the function to prevent the code from running multiple times at once or at all:

// your service
$scope.isRunning = false;

var getItems = function () {

    if(!$scope.isRunning){
        $scope.isRunning = true;
        var def = $q.defer();

        Items.get().then(function (items) {
           def.resolve(items);
        }, function (err) {
           ...
        }).finally(function(){
             //$scope.isRunning = false; // once done, reset isRunning to allow to run again. If you want it to run just once then exclude this line
        });
    }
};

Unsure how you want to handle the button in terms of being clicked multiple times

You can hide it on click:

<button ng-hide="isRunning">Stuff</button>

You can disable it on click:

<button ng-disabled="isRunning">Stuff</button>

if disabling, you should probably give feedback like changing opacity:

<button ng-disabled="isRunning" ng-class='{"opacity-half": isRunning}'>Stuff</button>
.opacity-half { opacity: 0.5 }

the below code should do the trick I am avoiding some angular specific syntax hope that helps;

function yourContoller(/*all injectables*/) {
  var requesting = false;
  $scope.buttonClick = function() {
     if (!requesting) {
       requesting = true;
       yourService.getItems().then(function(response) {
          /*your code to handle response*/
          requesting = false;
       });
     }
  };
}

if you want to disable a button in the view you can expose this variable by simply using scope ($scope.requesting = false;) with ng-disabled.

you can create a reusable directive so that on any button which is clickable, it doesnt get pressed twice

app.directive('clickAndDisable', function() {
  return {
    scope: {
      clickAndDisable: '&'
    },
    link: function(scope, iElement, iAttrs) {
      iElement.bind('click', function() {
        iElement.prop('disabled',true);
        scope.clickAndDisable().finally(function() {
          iElement.prop('disabled',false);
        })
      });
    }
  };
});

This can be used on a button as follows:

<button click-and-disable="functionThatReturnsPromise()">Click me</button>

本文标签: javascriptPrevent multiple ajax requests onclickStack Overflow