2013-06-28 23 views
12

Sono bloccato su un problema che riguarda una tabella di intestazione fissa. Sto utilizzando AngularJS & Bootstrap per creare un'applicazione web. Non riesco a utilizzare ng-grid perché non supporta IE7. Quindi, sto compilando le righe del tavolo per ng-repeat. L'applicazione è reattivo. Quindi, non posso dare una larghezza fissa alle celle/intestazioni. C'è un modo semplice per fissare le intestazioni della tabella?Tabella di intestazione fissa in AngularJS

Ho messo un Plunker a Fixed header table with AngularJS

Grazie in anticipo.

+0

I don Non capisco, vuoi che le intestazioni delle tabelle siano corrette ma anche reattive. Come è possibile? – Stewie

+0

@Stewie per favore guarda questo: http://www.fixedheadertable.com/ –

+0

@Stewie puoi anche fare l'esempio di ng-grid. Se si imposta l'intestazione fissa, rimane reattivo. –

risposta

-1

È meglio mantenere la parte dell'intestazione all'esterno del tavolo. Prendere due tabelle:

  • uno per intestazione e
  • un altro per i dati della tabella. (metti lo scroller solo nella parte dati tabella)

Buona fortuna!

+1

ma cosa succede se le larghezze delle righe sono calcolate in base al contenuto delle celle? –

0

Un collega ed io siamo appena rilasciato un nuovo progetto GitHub che fornisce una direttiva angolare che è possibile utilizzare per decorare la tavola con le intestazioni fisse: https://github.com/objectcomputing/FixedHeader

Questa implementazione non è così pieno di funzionalità come alcuni altre implementazioni, ma se il tuo bisogno è semplicemente di aggiungere tabelle fisse, pensiamo che questa potrebbe essere una buona opzione.

1

ho usato il suggerimento di Kumar e creato due tabelle. Uno contiene il thead e l'altro contiene sia il thead che il tbody.

<div ng-style="{'margin-right': scrollBarWidth}"> 
    <table> 
     <thead> 
     <tr> 
      <th width="{{tableSizes[0].width}}">Col0</th> 
      <th width="{{tableSizes[1].width}}">Col1</th> 
      <th width="{{tableSizes[2].width}}">Col2</th> 
     </tr> 
     </thead> 
    </table> 
</div> 
<div class="fixedHeadBody"> 
    <table ng-style="{'margin-top': -rowSize.height}"> 
     <thead> 
     <tr el-size="rowSize"> 
      <th el-size="{{tableSizes[0].width}}">Col0</th> 
      <th el-size="{{tableSizes[1].width}}">Col1</th> 
      <th el-size="{{tableSizes[2].width}}">Col2</th> 
     </tr> 
     </thead> 
     <tbody> 
     <!-- data goes here --> 
     </tbody> 
    </table> 
</div> 

Nel thead della seconda, ho aggiunto una direttiva (vedi sotto) che guarda la larghezza e l'altezza di ogni colonna. L'output di queste colonne viene utilizzato per impostare la larghezza del primo thead (binding angolare). Ho anche aggiunto la stessa direttiva a thead tr del secondo tavolo e uso il valore di altezza per nascondere il punto scorrevole del secondo tavolo. In questo modo, mostro solo il primo thead che è stato risolto.

Un'altra cosa che dovevo risolvere era la barra di scorrimento. La barra di scorrimento occupa spazio e disallinea le colonne tra la prima e la seconda tabella. Per risolvere questo problema, ho aggiunto un margine destro alla tabella superiore uguale alla larghezza della barra di scorrimento (differenza di larghezza tra il div che contiene la tabella e la tabella). La larghezza della barra di scorrimento varia tra i browser e l'ultima funzione funziona per qualsiasi browser.

app.directive('elSize', ['$parse', '$timeout', function ($parse, $timeout) { 
    return function(scope, elem, attrs) { 
     var fn = $parse(attrs.elSize); 

     scope.$watch(function() { 
      return { width: elem.innerWidth(), height: elem.innerHeight() }; 
     }, 
     function (size) { 
      fn.assign(scope, size); 
     }, true); 
    } 
}]) 

all'interno del controller, è possibile impostare la scrollBarWidth utilizzando la funzione qui sotto. Puoi chiamare $ scope.setScrollBarWidth() da qualsiasi posizione una volta che la tabella è stata renderizzata.

$scope.scrollBarWidth = "5px"; 
    $scope.setScrollBarWidth = function() { 
     $timeout(function() { 
      var divWidth = $(".fixedHeadBody").width(); 
      var tableWidth = $(".fixedHeadBody table").width(); 
      var diff = divWidth - tableWidth; 
      if (diff > 0) $scope.scrollBarWidth = diff + "px"; 
     }, 300); 
    } 
0

Bene, ha fatto il modo sporco con $ watch e jQuery.

Basta duplicare l'intestazione della tabella e renderla appiccicosa. Non è perfetto ma serve allo scopo.

Ecco il violino: http://jsfiddle.net/jchnxu/w1n1fp97/7/

// watch the width of table headers 
     scope.$watch(function() { 
      return { 
      width: $(th).innerWidth(), 
      height: $(th).innerHeight() 
      }; 
     }, function(size) { 
      console.log(size); 
      $($stickyThs[i]).attr('width', size.width); 
     }, true); 

// also watch the table width 
     scope.$watch(function() { 
     return $bodyTable.innerWidth(); 
     }, function(width) { 
     $headerTable.css('width', width + 'px'); 
     }); 
0

È possibile utilizzare l'eccellente libreria ag-Grid.

agGrid.initialiseAgGridWithAngular1(angular); // https://www.ag-grid.com/best-angularjs-data-grid/index.php 
angular.module('myApp', ['agGrid']) 

Poi nel controller definiscono un gridOptions (o un altro nome di variabile) come questo:

var nbCols = 10, 
    nbLines = 300, 
    list = [], 
    cols = [], 
    columnDefs = [], 
    i, j; 

for (i = 0 ; i < nbCols ; i++) { 
    var fieldName = 'col' + i; 
    cols.push(fieldName); 
    columnDefs.push({ 
     headerName: 'Col' + i, 
     field: fieldName, 
     editable: true 
    }); 
} 
for (i = 0 ; i < nbLines ; i++) { 
    var elem = {}; 
    for (j = 0 ; j < nbCols ; j++) { 
     elem[cols[j]] = 'content '+i+'-'+j; 
    } 
    list.push(elem); 
} 
$scope.list = list; 
$scope.cols = cols; 

$scope.gridOptions = { 
    columnDefs: columnDefs, 
    rowData: list, 
    singleClickEdit: true 
}; 

E infine definire il vostro tavolo come questo nel tuo HTML:

<div ag-grid="gridOptions" class="ag-fresh" style="height: 300px;"></div> 
Problemi correlati