Исправлена ​​таблица заголовков в AngularJS

Я столкнулся с проблемой, связанной с фиксированной таблицей заголовков. Я использую AngularJS и Bootstrap для создания веб-приложения. Я не могу использовать ng-grid, поскольку он не поддерживает IE7. Итак, я заполняю строки таблицы ng-repeat. Приложение отзывчивое. Таким образом, я не могу дать фиксированную ширину ячейкам/заголовкам. Есть ли простой способ, чтобы заголовки таблиц были исправлены?

Я положил Plunker на Исправлена ​​таблица заголовков с AngularJS

Спасибо заранее.

Ответ 1

Я создал директиву для этого недавно, вы можете установить его с помощью bower:

bower install angu-fixed-header-table

Для получения более подробной информации и рабочего примера вы можете увидеть мое сообщение в блоге http://pointblankdevelopment.com.au/blog/angularjs-fixed-header-scrollable-table-directive

Ответ 2

Я использовал предложение Кумара и создал две таблицы. Один содержит thead, а другой содержит как thead, так и 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>

Внутри второй, я добавил директиву (см. ниже), которая отслеживает ширину и высоту каждого столбца. Вывод этих столбцов используется для установки ширины первой привязки aad (angular). Я также добавил ту же директиву в thead tr второй таблицы и использую значение высоты, чтобы скрыть прокручиваемую thead второй таблицы. Таким образом, я показываю только первый апад, который исправлен.

Еще одна вещь, которую мне пришлось разобраться, это scrollBar. Полоса прокрутки занимает пробел и что несогласованность столбцов между первой и второй таблицами. Чтобы исправить это, я добавил margin-right в верхнюю таблицу, равную ширине полосы прокрутки (разность ширины между div, содержащим таблицу и таблицу). Ширина полосы прокрутки варьируется между браузерами, а последняя функция работает для любого браузера.

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);
    }
}])

Внутри контроллера вы можете установить scrollBarWidth, используя приведенную ниже функцию. Вы можете вызывать $scope.setScrollBarWidth() из любого места после рендеринга таблицы.

    $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);
    }

Ответ 3

Сотрудник, и я только что выпустил новый проект GitHub, который предоставляет директиву Angular, которую вы можете использовать для украшения вашей таблицы с помощью фиксированных заголовков: https://github.com/objectcomputing/FixedHeader

Эта реализация не так полно, как некоторые другие реализации, но если вам нужно просто добавлять фиксированные таблицы, мы считаем, что это может быть хорошим вариантом.

Ответ 4

Хорошо, сделал это грязным способом, используя $watch и jQuery.

Просто продублируйте заголовок таблицы и сделайте ее липкой. Это не идеально, но оно служит цели.

Здесь скрипка: 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');
      }); 

Ответ 5

Вы можете использовать отличную библиотеку ag-Grid.

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

Затем в вашем контроллере определите gridOptions (или другое имя переменной), подобное этому:

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
};

И, наконец, определите таблицу в этом HTML:

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

Ответ 6

Лучше сохранить часть заголовка вне таблицы. Возьмите две таблицы:

  • один для заголовка и
  • другой для табличных данных. (поместите скроллер только в таблицу данных.)

Удачи!