1. 程式人生 > >angular自定義點選元件防止多次請求

angular自定義點選元件防止多次請求

第一次寫部落格不知道寫什麼,寫個前段時間解決的一個問題作為第一篇文吧(哈哈)。 做專案的時候,經常碰到網不好請求慢的時候使用者就會多次進行點選,導致提交多次請求,為了阻止這種情況,自己寫了一個點選元件,替換掉原本使用的ng-click。剛開始的時候也是去網上找解決方法,但是網上的多是阻止雙擊的,並不能滿足我需要的效果,後來突然發現$http有個pendingRequests屬性——當前正在等待的請求的配置物件陣列,正好可以用來判斷當前請求是否結束了。

結合用$timeout來阻止雙擊事件的寫法,最後寫法如下:

.directive('singleClick',function ($parse, $rootScope, $timeout, $http) {
      var clickable = true;
      var directiveName = 'singleClick';
      return {
          restrict: 'A',
          link: function(scope, iElement, attr) {
              var fn = $parse(attr[directiveName], null, true);
              iElement.on('click', function(event) {
           
                  if (!clickable) {
                      event.preventDefault();//阻止預設事件
                      event.stopImmediatePropagation();//阻止所有事件傳播 
                      return
                  }
                  else {
                      clickable = false;
                      $timeout(function () { 
                          clickable = true;
                      }, 500, false);
                  }

                  if($http.pendingRequests.length > 0){
                      event.preventDefault();//阻止預設事件
                      event.stopImmediatePropagation();//阻止所有事件傳播 
                      return
                  }

                  scope.$apply(function() {
                      fn(scope, {$event:event});
                  })
              });
          }
      };
  })

然後將頁面中的ng-click=“func()” 改成 single-click=“func()”。

如果是希望針對按鈕有一個禁止的效果,可以使用watchwatch監聽http.pendingRequests然後設定按鈕的禁用啟用,這樣在請求完成之前按鈕就一直處於不可點選狀態:

    element.prop('disabled',true);
	scope.isLoading = function () {
        return $http.pendingRequests.length > 0;
    };
    var clickWatch = scope.$watch(scope.isLoading, function (loading){
        if(loading){
        	element.prop('disabled',true);
        }else{
        	element.prop('disabled',false);
        	clickWatch();
        }
    });
    scope.$apply(function() {
         fn(scope, {$event:event});
     })