Подтвердить что ты не робот

Angular ui-grid динамически вычисляет высоту сетки

Я использую: https://github.com/angular-ui/ui-grid.info/tree/gh-pages/release/3.0.0-RC.18

<div ui-grid="gridOptions" style="height:765px"></div>

Когда я жестко кодирую значение, как показано выше, сетка распространяется и все работает так, как ожидалось.

Однако, если я делаю следующее...

$scope.gridStyle = 'height:'+numRows*rowHeight+'px' //(765px);
<div ui-grid="gridOptions" style="{{gridStyle}}"></div>

Высота печатается в div и div расширяется, но сам контент расширяется только до 340 пикселей. Пробел остается пустым, поэтому вместо 25 строк я вижу только 8. Мне нужно прокручивать вниз, в то время как в сетке есть всего 400 пикселей. Виджет ui-grid-viewport и ui-grid-canvas не используют это пространство...

Почему не может использовать экранное окно ui-grid-view?

4b9b3361

Ответ 1

Я использую ui-grid - v3.0.0-rc.20, потому что проблема с прокруткой исправлена ​​, когда вы переходите на полную высоту контейнера. Использование модуля ui.grid.autoResize будет динамически автоматически изменять размер сетки в соответствии с вашими данными. Для расчета высоты сетки используйте функцию ниже. ui-if необязательно ждать, пока ваши данные не будут установлены перед рендерингом.

angular.module('app',['ui.grid','ui.grid.autoResize']).controller('AppController', ['uiGridConstants', function(uiGridConstants) {
    ...
    
    $scope.gridData = {
      rowHeight: 30, // set row height, this is default size
      ...
    };
  
    ...

    $scope.getTableHeight = function() {
       var rowHeight = 30; // your row height
       var headerHeight = 30; // your header height
       return {
          height: ($scope.gridData.data.length * rowHeight + headerHeight) + "px"
       };
    };
      
    ...
<div ui-if="gridData.data.length>0" id="grid1" ui-grid="gridData" class="grid" ui-grid-auto-resize ng-style="getTableHeight()"></div>

Ответ 2

В более простом подходе используется css в сочетании с установкой значений minRowsToShow и virtualizationThreshold динамически.

В таблице стилей:

.ui-grid, .ui-grid-viewport {
    height: auto !important;
}

В коде вызовите функцию ниже при каждом изменении data в gridOptions. maxRowToShow - это значение, которое вы предварительно определили, для моего варианта использования я установил его на 25.

ES5:

setMinRowsToShow(){
    //if data length is smaller, we shrink. otherwise we can do pagination.
    $scope.gridOptions.minRowsToShow = Math.min($scope.gridOptions.data.length, $scope.maxRowToShow);
    $scope.gridOptions.virtualizationThreshold = $scope.gridOptions.minRowsToShow ;
}

Ответ 3

UPDATE

HTML был запрошен, поэтому я вставил его ниже.

<div ui-grid="gridOptions" class="my-grid"></div>

ОРИГИНАЛ

Мы смогли адекватно решить эту проблему, используя отзывчивый CSS (@media), который устанавливает высоту и ширину на основе экранной недвижимости. Что-то вроде (и, безусловно, вы можете добавить больше, исходя из ваших потребностей):

@media (min-width: 1024px) {
  .my-grid {
    width: 772px;
  }
}

@media (min-width: 1280px) {
  .my-grid {
    width: 972px;
  }
}

@media (min-height: 768px) {
  .my-grid {
    height: 480px;
  }
}

@media (min-height: 900px) {
  .my-grid {
    height: 615px;
  }
}

Лучшая часть этого решения заключается в том, что нам не нужна обработка событий с изменением размера для отслеживания изменений размера сетки. Он просто работает.

Ответ 4

Мне нравится подход Тони. Он работает, но я решил реализовать по-другому. Здесь мои комментарии:

1) Я сделал несколько тестов, и при использовании ng-стиля Angular оценивает содержимое ng-стиля, я имею в виду функцию getTableHeight() более одного раза. Я поставил точку останова в функцию getTableHeight(), чтобы проанализировать это.

Кстати, ui-if был удален. Теперь у вас есть ng-if build-in.

2) Я предпочитаю писать такую ​​услугу:

angular.module('angularStart.services').factory('uiGridService', function ($http, $rootScope) {

var factory = {};

factory.getGridHeight = function(gridOptions) {

    var length = gridOptions.data.length;
    var rowHeight = 30; // your row height
    var headerHeight = 40; // your header height
    var filterHeight = 40; // your filter height

    return length * rowHeight + headerHeight + filterHeight + "px";
}
factory.removeUnit = function(value, unit) {

    return value.replace(unit, '');
}
return factory;

});

И затем в контроллере напишите следующее:

  angular.module('app',['ui.grid']).controller('AppController', ['uiGridConstants', function(uiGridConstants) {

  ...

  // Execute this when you have $scope.gridData loaded...
  $scope.gridHeight = uiGridService.getGridHeight($scope.gridData);

И в файле HTML:

  <div id="grid1" ui-grid="gridData" class="grid" ui-grid-auto-resize style="height: {{gridHeight}}"></div>

Когда Angular применяет стиль, он должен смотреть только в переменную $scope.gridHeight и не оценивать полную функцию.

3) Если вы хотите динамически рассчитать высоту расширяемой сетки, это сложнее. В этом случае вы можете установить свойство expandableRowHeight. Это фиксирует зарезервированную высоту для каждой подсерии.

    $scope.gridData = {
        enableSorting: true,
        multiSelect: false,  
        enableRowSelection: true,
        showFooter: false,
        enableFiltering: true,    
        enableSelectAll: false,
        enableRowHeaderSelection: false, 
        enableGridMenu: true,
        noUnselect: true,
        expandableRowTemplate: 'subGrid.html',
        expandableRowHeight: 380,   // 10 rows * 30px + 40px (header) + 40px (filters)
        onRegisterApi: function(gridApi) {

            gridApi.expandable.on.rowExpandedStateChanged($scope, function(row){
                var height = parseInt(uiGridService.removeUnit($scope.jdeNewUserConflictsGridHeight,'px'));
                var changedRowHeight = parseInt(uiGridService.getGridHeight(row.entity.subGridNewUserConflictsGrid, true));

                if (row.isExpanded)
                {
                    height += changedRowHeight;                    
                }
                else
                {
                    height -= changedRowHeight;                    
                }

                $scope.jdeNewUserConflictsGridHeight = height + 'px';
            });
        },
        columnDefs :  [
                { field: 'GridField1', name: 'GridField1', enableFiltering: true }
        ]
    }

Ответ 5

подход tony работает для меня, но когда вы выполняете console.log, функция getTableHeight вызывает слишком много времени (сортировка, щелчок меню...)

Я изменяю его так, чтобы высота пересчитывалась только при добавлении/удалении строк. Примечание: tableData - это массив строк

$scope.getTableHeight = function() {
   var rowHeight = 30; // your row height
   var headerHeight = 30; // your header height
   return {
      height: ($scope.gridData.data.length * rowHeight + headerHeight) + "px"
   };
};

$scope.$watchCollection('tableData', function (newValue, oldValue) {
    angular.element(element[0].querySelector('.grid')).css($scope.getTableHeight());
});

HTML

<div id="grid1" ui-grid="gridData" class="grid" ui-grid-auto-resize"></div>

Ответ 6

следуя подходу @tony, изменили функцию getTableHeight() на

<div id="grid1" ui-grid="$ctrl.gridOptions" class="grid" ui-grid-auto-resize style="{{$ctrl.getTableHeight()}}"></div>

getTableHeight() {
    var offsetValue = 365;
    return "height: " + parseInt(window.innerHeight - offsetValue ) + "px!important";
}

сетка будет иметь динамическую высоту и относительно высоты окна.

Ответ 7

.ui-grid,.ui-grid-viewport,.ui-grid-contents-wrapper,.ui-grid-canvas {       высота: auto! important;   }