阿里云新用户优惠

七、UI-Grid Hidden Grids 隐藏的表格

原文:108 Hidden Grids

当UI-Grid在页面加载的时候不是可见状态,比如在tabset页面中,或者是在可折叠的页面内。最终的结果往往是一个表格呈现出“错误”或者行列出现意想不到的宽度或高度。

让我们从这个场景开始:想象一下,在一个<div>内的表格,这个<div>没有宽度或高度。您提供的表格没有CSS类,所以它的高度和宽度CSS值设置为自动,这意味着浏览器将自动计算。

UI-Grid的出现是为了显示大量的数据更容易。它通过一个称为“虚拟化”的过程。这意味着,如果你有10000行 * 50列的数据,UI-Grid将只显示其所需的最小数量展现给用户,而不是渲染出500000个DOM元素来拖慢浏览器。对用户来说,看起来所有的数据都在屏幕上,事实上只有一小部分正在渲染。

这将成为我们在上面创建的场景中的一个问题,因为当我们告诉UI-Grid,我们有10000行和50列时,它知道我们实际上不想同时显示它们,所以它必须找出可见的空间,允许它“绘制”。这个空间被称为“窗口”,我们通过这个“窗口”来查看数据,这个窗口外都是空的内容,除了我们滚动时添加出现的行和列。

当你把UI-Grid放在没有指定高度的容器div中,网格没有CSS指定的高度时,它就不知道你希望它有多大。你想看5行吗?100?它不能告诉。目前这只是假设,在窗口中10行是一个很好的默认值。可以通过minRowsToShow 设置这个值。

如果你给UI-Grid的高度100%,但它的父容器div没有高度?然后它也不知道它应该有多大。100%什么?什么也没有?所以,它会调整大小以适应minRowsToShow所指定的行数。还可以通过给表格一个特定的高度来解决这个问题,或可变的高度并给父容器一个有效的高度或父容器内放置其他元素,比如有一个图像和表格在同一容器中,并且图像的高度是500px,表格的指定高度是:50%,那么表格的高度就是250px。

让我们看一下表格在隐藏的情况下,无论是在一个标签或折叠菜单或ng-show表达式。隐藏元素没有高度或宽度,因为他们未被渲染。如果设置一个元素的CSS属性为display: none,并注销其offsetWidth 属性,这个元素将为0。即使当它可见时的高度有1000px,当它隐藏后它没有高度。UI Grid也是像JQuery这样处理,创建一个“虚拟”克隆的元素,元素属性display: none改变为visibility: hidden(这意味着它是不可见的但仍占用空间),然后将这个克隆的元素附加到上,计算它的高度,最后删除它。是唯一安全的地方,因为当隐藏的元素占用空间时,它可以导致周围其他元素的移动,并出现“闪烁”的效果。

所以当你把表格放在一个没有渲染的地方,并且表格的CSS没有设置它有多大,当它创建这个克隆元素并测量它时,它的高度和宽度将为0。即使0px太小,UI-Grid也会尽力调整,所以它会调整到可用高度,但真的没有办法告诉它应该有多宽,所以列会是最小宽度(30px左右),窗口将会很小,看起来像UI-Grid渲染错误,而且窗口太小的表格单元本身会占用父容器的宽度。

为了解决这个问题,你必须给表格一些设置。这里有一些选项:

在下面的例子中给表格一个特定的高度和宽。 用 ng-if 来防止表格在元素(面板/折叠/等)被激活前渲染。 使用 autoResize 让表格重新绘制,这可能会导致页面闪烁,autoResize 的检测周期是250ms。

  • index.html
<!doctype html>
<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.css"></script>
    <script src="app.js"></script>
  </head>
  <body>
    <div ng-controller="MainCtrl">
      <button type="button" class="btn btn-success" ng-click="hideGrid = !hideGrid">
        {{ hideGrid && 'Show' || 'Hide' }} Grid
      </button>

      <div class="well" ng-hide="hideGrid">
        <div ui-grid="gridOptions" class="grid"></div>
      </div>
    </div>
  </body>
</html>
  • main.css
.grid {
  width: 500px;
  height: 150px;
}
  • app.js
var app = angular.module('app', ['ngTouch', 'ui.grid']);

app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
  $scope.hideGrid = true;

  $scope.gridOptions = {  };

  $http.get('http://ui-grid.info/data/100.json')
    .success(function(data) {
      $scope.gridOptions.data = data;
    });
}]);

关注微信公众号,与我交流吧~

分享