问题
I have found many questions about UI Grid autowidth issue. I managed to reproduce one of them and would like to share with you the details on how to reproduce it.
First, I have the default UI Grid inside of a hidden modal (you can find the code snippet at the end of this post).
Steps to reproduce:
Run the code snippet, press "Launch demo modal"; (there is no issues);
Close the modal;
- Resize browser window. here it is. Column width is reset to a wrong value.
var app = angular.module('app', ['ui.grid']); app.controller('MainCtrl', ['$scope', '$http', 'uiGridConstants', function ($scope, $http, uiGridConstants) { $scope.gridOptions1 = { enableSorting: true, columnDefs: [ { field: 'name' }, { field: 'gender' }, { field: 'company', enableSorting: false } ], onRegisterApi: function( gridApi ) { $scope.grid1Api = gridApi; } }; $scope.gridOptions1.data = [ { name: 1, gender: 2, company: 3 }, { name: 1, gender: 2, company: 3 }, { name: 1, gender: 2, company: 3 }, { name: 1, gender: 2, company: 3 }, { name: 1, gender: 2, company: 3 }]; }]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css" rel="stylesheet"/> <link href="https://rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.css" rel="stylesheet"/> <script src="https://rawgit.com/HubSpot/tether/master/dist/js/tether.js"></script> <script src="https://rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-touch.js"></script> <script src="https://rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.js"></script> <!-- Button trigger modal --> <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> Launch demo modal </button> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title" id="myModalLabel">Modal title</h4> </div> <div class="modal-body" ng-app="app"> <div ng-controller="MainCtrl"> <div id="grid1" ui-grid="gridOptions1" class="grid"></div></div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div>
回答1:
Also I would like to share with you an approach of fixing it.
Actually, there are two bugs here.
- UI Grid is set to 0 on page resize when modal is hidden;
- UI Grid is set to 0 on page load.
The first one is easy to detect and fix if you use uncompressed version of UI Grid:
There reason of both issues is the same. The width of hidden element is zero.
A simple workaround with jQuery will be as follows for the first case:
// Resize the grid on window resize events
function gridResize($event) {
grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm);
grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
console.log(grid.gridWidth);
console.log(grid.gridHeight);
if(!$($elm).is(':hidden') && grid.gridWidth > 0) { //add such if statement before
grid.refreshCanvas(true); //this is UI Grid code
}
}
The second case is not so simple to fix. Because we need to get the width of Grid container ( in this case modal is the container ).
Container might be inside of a hidden element ( that means jQuery(gridContainer).width()
will return zero ).
That is how I came across jQuery.actual
plugin (github or demo). I will use it to show you a solution for this specific case:
// Initialize the directive
function init() {
if($($elm).is(':hidden')) { //added
grid.gridWidth = $scope.gridWidth = $($elm).parent().actual('width'); //added
} //added
else { //added
grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm); //this is UI Grid code
} //added
}
As result we will get a UI Grid with proper auto width feature.
Finally, we do not need $Interval
workaround from the tutorial with this approach.
来源:https://stackoverflow.com/questions/35246402/ui-grid-v3-1-0-column-auto-width-issue-detected