2015-10-21 23 views
5

Sto provando a fare una direttiva che posso fare una scroll virtuale, così come l'utente fa scorrere la tabella, la tabella rimuove le "vecchie" visualizzazioni e aggiunge "nuove" viste, tipo la ripetizione della raccolta ma sono stato in mancanza, penso di non aver capito la matematica dietro, qualcuno può aiutarmi?Come posso creare uno scroll virtuale con angularJS?

questo è il mio codice di direttiva:

BaseModule.directive('myScroll', function() { 
    return { 
     restrict:"A", 
     scope:{ 
      rows:"=", 
      headers:"=" 
     }, 
     link: function(scope,el) { 
      var scrollTop = 0; 
      var scrollLeft = 0; 
      angular.element(el).on('scroll',function(){ 
       scrollTop = $(el).scrollTop(); 
       scrollLeft = $(el).scrollLeft(); 
       $(el).parent().find(".header").scrollLeft(scrollLeft); 
       var height = $(el).height(); 
       var numberOfRows = height/23; 
       var initialRow = scrollTop/23; 
       var html = ""; 
       for(i=0; i<numberOfRows;i++){ 
        var row = scope.rows[i+initialRow]; 
        html = html + addRow(row,i+initialRow); 
       } 
       $(el).find('.tbody-scroll').append(html); 
      }); 
      scope.$watch('rows',function(rows){ 
       var height = $(el).height(); 
       var numberOfRows = height/23; 
       var initialRow = scrollTop/23; 
       var html = ""; 
       for(i=0; i<numberOfRows;i++){ 
        var row = rows[i+initialRow]; 
        html = html + addRow(row,i+initialRow); 
       } 
       $(el).find('.tbody-scroll').append(html); 
      }); 
      var addRow = function(row,index){ 
       var html = ""; 
       var pos = 0; 
       var totalWidth = 0; 
       angular.forEach(row,function(col){ 
        var width = scope.headers[pos].width; 
        totalWidth = totalWidth + width; 
        html = html + "<span style='width:"+width+"px'>"+col.value+"</span>"; 
        pos++; 
       }); 
       html = "<div class='row' style='top:"+index*23+"px;width:"+totalWidth+"px;'>"+html; 
       html = html + "</div>"; 
       return html; 
      }; 
     } 
    }; 
}); 

<!-- my directive .html --> 
<div class="mTable"> 
    <div class="header" ng-style="headerWidth(headers())"> 
     <span ng-repeat="header in headers()" ng-style="widthStyle(header)"> 
      {{::header.label}} 
     </span> 
    </div> 
    <div class="tbody-container" my-scroll headers="headers()" rows="rows()"> 
     <div class="tbody-scroll" ng-style="scrollHeight(rows(),headers())"></div> 
    </div> 
</div> 

risposta

2

Dare una risposta completa con il codice potrebbe richiedere un po 'troppo di uno sforzo
Questa libreria implementa scroll virtuale su ng-repeat https://github.com/stackfull/angular-virtual-scroll nella descrizione c'è anche un articolo su come implementare questa funzionalità da solo.

L'idea di base è di creare due div, uno sopra e uno sotto l'elenco, la cui dimensione è determinata dal numero di elementi all'interno dell'elenco (questo approccio ha una limitazione poiché gli elementi dell'elenco devono avere la stessa altezza o la loro altezza deve essere corretta), quindi si eliminano gli elementi man mano che scompaiono dal viewport e si ridimensionano i div in base al numero di elementi non correntemente visualizzati e la propria posizione nell'elenco

+1

Ho già visto questa direttiva in precedenza e non avevo successo ma all'improvviso mi sono reso conto che non funzionava solo per il css di div e ora ho capito, quindi accetterò il tuo –

+0

Contento di essere stato di aiuto, in qualche modo – valepu

+1

Hai fatto, visto che questa direttiva mi ha fatto di nuovo pensa "prova di nuovo fratello " quindi grazie!!! –

2

Non è una risposta diretta alla sua domanda, ma un'alternativa: Si consiglia di guardare il ui-scroll directive che è un sostituto per ng-repeat e ha una funzione simile .

Esempio nel controller

$scope.movieDataSource = { 

    get : function (index, count, callback) { 
     var i, items = [$scope.userMovies], item; 

      var min = 1; 
      var max = 1000; 

     for (i=index ; i<index + count ; i++) { 
       if(i < min || i > max) { 
        continue; 
       } 
      item = { 
       title: $scope.userMovies.title, 
       imageURL: $scope.userMovies.poster_path 
      }; 
      items.push (item); 
     } 
     callback (items); 
    } 
} 

E secondo lei:

<div ui-scroll="item in movieDataSource"> 
    {{item.title}} 
</div>