programing

각도 UI 그리드가 그리드의 높이를 동적으로 계산합니다.

telecom 2023. 3. 31. 21:34
반응형

각도 UI 그리드가 그리드의 높이를 동적으로 계산합니다.

사용하고 있는 것은 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에 인쇄되지만 내용 자체는 약 340px로 확대됩니다.남은 공간이 비어 있기 때문에 25줄 대신 8줄만 표시됩니다.400ppx의 빈 공간이 있는 동안 아래로 스크롤해야 합니다.ui-grid-viewport 및 ui-grid-canvas 모두 이 공간을 사용하지 않습니다.

ui-grid-viewport에서 해당 공간을 사용할 수 없는 이유는 무엇입니까?

사용하고 있다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>

보다 심플한 어프로치가 사용되다css셋업과 조합하여minRowsToShow그리고.virtualizationThreshold동적으로 평가합니다.

스타일시트:

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

코드에서는, 다음의 함수를 변경할 때마다 호출해 주세요.datagridOptions.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 ;
}

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

갱신:

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

이 솔루션의 가장 큰 장점은 그리드 크기 변경을 모니터링하기 위해 이벤트 처리 크기를 조정할 필요가 없다는 것입니다.효과가 있어요.

토니의 접근법이 좋아요.효과는 있지만, 저는 다른 방법으로 구현하기로 했습니다.코멘트는 다음과 같습니다.

1) 몇 가지 테스트를 했는데, Angular가 ng 스타일의 콘텐츠를 평가할 때 getTableHeight() 함수를 여러 번 사용하였습니다.이를 분석하기 위해 getTableHeight() 함수에 브레이크 포인트를 넣었습니다.

참고로 ui-if는 삭제되었습니다.이것으로 ng-if 빌트인이 되었습니다.

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) 확장 가능한 그리드의 높이를 동적으로 계산하려면 더 복잡합니다.이 경우 expandableRow를 설정할 수 있습니다.높이 속성.그러면 각 서브그리드의 예약된 높이가 변경됩니다.

    $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 }
        ]
    }

Tony의 접근방식은 나에게 효과가 있지만 console.log를 실행하면 getTableHeight 함수가 너무 많이 호출된다(sort, menu click...)

행을 추가하거나 제거할 때만 높이가 다시 계산되도록 수정합니다.주의: 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>

나는 게임에 늦었지만 좋은 해결책을 찾았다.커스텀 속성 디렉티브를 작성했습니다.gridApi를 전달하기만 하면 높이가 자동으로 계산됩니다.또한 페이지 번호 변경 이벤트에 가입하므로 사용자가 페이지 크기를 변경하면 크기가 변경됩니다.

class UIGridAutoResize implements ng.IDirective {
    link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => void;
    scope: { gridApi: "=" };
    restrict = "A";

    private previousValue: string;
    private isValid: boolean = true;
    private watch: any;

    constructor($timeout: ng.ITimeoutService) {
        UIGridAutoResize.prototype.link = (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => {
            const gridOptions = scope.$eval(attrs.uiGrid) as any;
            const gridApi = scope.$eval(attrs.gridResize) as any;

            gridApi.core.on.rowsRendered(scope, () => {
                $timeout(() => {
                    this.autoSizeGrid(element, attrs, gridOptions, gridApi, false);
                }, 100);
            });

            gridApi.core.on.filterChanged(scope, () => {
                this.autoSizeGrid(element, attrs, gridOptions, gridApi, false);
            });

            if (attrs.uiGridPagination === "") {
                gridApi.pagination.on.paginationChanged(null, () => {
                    this.autoSizeGrid(element, attrs, gridOptions, gridApi, true);
                });
            }

            angular.element(window).resize(() => {
                $timeout(() => {
                    this.autoSizeGrid(element, attrs, gridOptions, gridApi, false);
                }, 100);
            });
        };
    }

    static Factory(): ng.IDirectiveFactory {
        const directive = ($timeout: ng.ITimeoutService) => {
            return new UIGridAutoResize($timeout);
        };

        directive["$inject"] = ["$timeout"];

        return directive;
    }

    private autoSizeGrid(element: ng.IAugmentedJQuery, attrs: ng.IAttributes, gridOptions: any, gridApi: any, isPaginationChanged: boolean) {
        gridApi.core.handleWindowResize();

        // Clear empty grid message 
        angular.element(element.parent()).find("#emptyGridMessage").remove();
        element.find(".ui-grid-viewport").css("display", "");

        if (attrs.hidePageSize === "") {
            element.find(".ui-grid-pager-row-count-picker").css("display", "none");
        }

        let rowCount = gridApi.core.getVisibleRows().length;

        const headerElements = element.find(".ui-grid-header");
        let headerHeight = 2;

        if (headerElements.length > 1) { // If we have more than one header element the grid is using grouping
            const headerElement = angular.element(headerElements[1]);
            headerHeight += headerElement.height();
        } else {
            headerHeight += headerElements.height();
        }

        if (attrs.uiGridPagination === "") {
            if (rowCount < 1) {
                gridOptions.enablePagination = false;
                gridOptions.enablePaginationControls = false;
                element.css("height", (rowCount * 30) + headerHeight - 2);
                element.find(".ui-grid-viewport").css("display", "none");
                angular.element("<div id='emptyGridMessage' style='font-size: 1em; width: 100%; background-color: white; border: 1px solid #d4d4d4; padding: 7px 12px; color: #707070;'><span style='opacity: 0.95;'>There are no records.</span></div>").insertAfter(element);
            } else if (gridApi.core.getVisibleRows().length < gridOptions.paginationPageSize && !isPaginationChanged) {
                gridOptions.enablePagination = false;
                gridOptions.enablePaginationControls = false;
                element.css("height", (rowCount * 30) + headerHeight);
            } else {
                gridOptions.enablePagination = true;
                gridOptions.enablePaginationControls = true;              
                element.css("height", (rowCount * 30) + headerHeight);
            }
        } else {
            if (rowCount < 1) {
                element.css("height", (rowCount * 30) + headerHeight - 2);
                element.find(".ui-grid-viewport").css("display", "none");
                angular.element("<div id='emptyGridMessage' style='font-size: 1em; width: 100%; background-color: white; border: 1px solid #d4d4d4; padding: 7px 12px; color: #707070;'><span style='opacity: 0.95;'>There are no records.</span></div>").insertAfter(element);
            } else {
                element.css("height", (rowCount * 30) + headerHeight);
            }
        }

        // Add extra margin to prevent scroll bar and pager from overlapping content underneath
        const pagerHeight = element.find(".ui-grid-pager-panel").height();

        if (rowCount > 0) {
            if (pagerHeight > 0)
                element.css("margin-bottom", pagerHeight);
            else
                element.css("margin-bottom", 10);
        } else {
            if (pagerHeight > 0)
                angular.element(element.parent()).find("#emptyGridMessage").css("margin-bottom", pagerHeight);
            else 
                angular.element(element.parent()).find("#emptyGridMessage").css("margin-bottom", 10);
        }

        if (rowCount > gridOptions.paginationPageSize) // Sometimes paging shows all rows this fixes that
           gridApi.core.refresh();
    }
}
<div ui-grid="vm.gridOptions" grid-resize="vm.gridApi" ui-grid-resize-columns ui-grid-pagination></div>

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

그리드는 창 높이와 관련하여 동적 높이도 갖습니다.

언급URL : https://stackoverflow.com/questions/27837335/angular-ui-grid-dynamically-calculate-height-of-the-grid

반응형