2016-04-26 51 views
2

我有一個AngularJS項目(我不使用JQuery),我需要顯示一個用戶的表格,並在用戶滾動頁面附近時加載更多。我試圖在不依賴外部庫的情況下實現這一點,因爲這是我的要求的一部分。如何正確實現無JQuery滾動的AngularJS表?

我檢查了幾個例子,如this,thisthis

但到目前爲止,我沒有檢查過的例子幫助我實現了無限滾動,如我所料。他們使用不同的方式來計算何時觸發調用,其中一些值返回給我未定義(即人們說clientHeight和scrollHeight有不同的值,但對我來說它總是相同的,總高度包括滾動空間)。

我創建像下面這樣的指令:

usersModule.directive('whenScrollEnds', function($window) { 
    return { 
     restrict: "A", 
     link: function(scope, elm, attr) { 

      angular.element($window).bind('scroll', function() { 

      var hiddenContentHeight = elm[0].scrollHeight - angular.element($window)[0].innerHeight; 

      if ((hiddenContentHeight - angular.element($window)[0].scrollY) <= (10)) { 
       angular.element($window)[0].requestAnimationFrame(function(){ 
       scope.$apply(attr.whenScrollEnds); 
       }) 
      } 

      }); 
     } 
    }; 
}); 

這類作品,但有下列問題/疑慮,我希望有人能向我解釋:

  • 它觸發太快。當我接近可滾動空間的底部時,我想要觸發加載,例如接近90%左右。
  • scrollHeight只能通過elm [0]訪問,angular.element($ window)[0]沒有scrollHeight屬性,所以它返回undefined,而elm [0]沒有scrollY值。
  • 我得到的scrollY值是滾動條從頂部移動的距離減去滾動條的長度,但我覺得這個值是錯誤的。
  • 通過angular.element($ window)綁定滾動事件.bind正確的決定?

我該如何實現一個合適的無限滾動表?我使用了正確的變量嗎?請提供僅使用Javascript和AngularJS的答案,JQuery或庫解決方案不會幫助我。

回答

3

在檢查了幾個例子並試圖避免那些使用JQuery作爲解決方案的一部分之後,我找到了一種方法來完成這項工作。

首先我的指令,當滾動結束,將處理:

usersModule.directive('whenScrollEnds', function($window) { 
    return { 
     restrict: "A", 
     link: function(scope, elm, attr) { 
      var raw = elm[0]; 

      raw.addEventListener('scroll', function() { 
      if ((raw.scrollTop + raw.clientHeight) >= (raw.scrollHeight)) { 
       scope.$apply(attr.whenScrollEnds); 
      } 
      }); 
     } 
    }; 
}); 

我的觀點有div像這裏面的表格:

<div id="usersScrollable" when-scroll-ends="uc.loadMoreUsers()"> 
    <table id="tableUsers" class="table" ng-show="uc.users.length" > 
     <thead> 
     <tr> 
     <th>Email</th> 
     <th>Nombre Completo</th> 
     <th>Estado</th> 
     <th>Acción</th> 
     </tr> 
     </thead> 
     <tbody > 
     <tr ng-repeat="u in uc.users"> 
     <td>{{u.email}}</td> 
     <td>{{u.fullName}}</td> 
     <td>{{uc.getStateString(u.active)}}</td> 
     <td><button type="button" class="btn btn-primary" ng-click="uc.edit(u)">Editar</button></td> 
     </tr> 
     </tbody> 
    </table> 
    </div> 

確保包含該表的div是一個在聽滾動結束的時候。這div必須有一個設置的高度,如果它不然clientHeight財產將與scrollHeight相同(不知道如果沒有明確定義高度會發生什麼,而不是設置您設置頂部或底部屬性的高度)。

在我的控制器,loadMoreUsers()負責遞增頁面(如果有多個用戶,每個呼叫我得到了總用戶的,所以我可以做另一個請求有多少用戶,我已經離開之前知道),也它調用向Web服務發出請求的函數。

0

與烏列Arvizu提供的解決方案的問題是,如果raw元素是空的,因爲它在等待頁面加載一個HTTP請求,以下所有raw.scrollTopraw.clientHeight)raw.scrollHeight都會有錯誤的尺寸和滾動不再工作了。

我建議這個其他解決方案基本上將滾動事件添加到$window而不緩存它,所以當收到Http響應時它的大小總是正確的。

(function() { 
    'use strict'; 

    angular.module('ra.infinite-scroll', []).directive('infiniteScroll', function ($window) { 
     return { 
      restrict: 'A', 
      scope: { 
       infiniteScrollCallbackFn: '&' 
      }, 
      link: function (scope, elem, attrs) { 
       var percentage = (attrs.infiniteScrollPercentage !== undefined ? (attrs.infiniteScrollPercentage/100) : '.9'); 
       var $element = elem[0]; 

       angular.element($window).on('scroll', function() { 
        if ((this.scrollY + this.innerHeight - $element.offsetTop) >= ($element.scrollHeight * percentage)) { 
         scope.$apply(scope.infiniteScrollCallbackFn); 
        } 
       }); 
      } 
     }; 
    }); 
})(); 

另外,在該模塊中,可以通過2個參數中的HTML:一個回調函數和特定元件的百分比(其中模塊被施加)在達到時,它的回調函數被調用,即重複Http請求(默認是該元素的90%)。

<div infinite-scroll infinite-scroll-callback-fn="callBackFunction()" infinite-scroll-percentage="80"> 
     // Here you may include the infinite repeating template 
    </div>