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?
Ответы
Ответ 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; }