如何在AngularJS ui-grid中自动调整列宽

15
在AngularJS ui-grid中,我如何配置网格以使其能够根据内容自动调整列的宽度? 我知道有一个tutorial展示了自动大小功能,但仅当您双击该列时才有效,我希望它在初始化网格时就能自动适应。

1
那么你尝试过的代码在哪里呢? - ajmajmajma
12个回答

6

在您的列定义中使用星号:

width:"*";

2
这个没有报错,但是似乎不起作用。列仍然只能通过手动调整大小来改变。 - Charles Roper
请发布您的列定义,以便我查看。 - cramroop
以下是我的columnDefs: https://gist.github.com/charlesroper/726d2df8d769920966ee。前三列应该自动调整大小,对吧?在我的情况下,它们的宽度与所有其他列相同,并且标头中的分隔线可以双击调整它们的大小。这是一个非常新的功能吗?如果是这样,可能是我没有最新版本的ui-grid。 - Charles Roper
1
@CharlesRoper 你解决了吗?我无法让列自动调整大小。这让我很疯狂。 - Matthias Max
@MatthiasMax 不,我不认为我曾经这样做过。 - Charles Roper

5

4
我认为目前还没有此功能。uiGridColumnResizer指令会在双击、鼠标按下和鼠标抬起时注册事件监听器。双击事件基本上会浏览所有渲染的单元格并计算最大宽度,然后将其设置为列宽。如果您渲染了很多行,则这将是一个性能问题。
我可能只会基于网格数据设置最大可能的宽度。
或者尝试在uiGridColumnResizer中复制此行为。
 $elm.on('dblclick', function(event, args) {
      event.stopPropagation();

      var col = uiGridResizeColumnsService.findTargetCol($scope.col, $scope.position, rtlMultiplier);

      // Don't resize if it's disabled on this column
      if (col.colDef.enableColumnResizing === false) {
        return;
      }

      // Go through the rendered rows and find out the max size for the data in this column
      var maxWidth = 0;
      var xDiff = 0;

      // Get the parent render container element
      var renderContainerElm = gridUtil.closestElm($elm, '.ui-grid-render-container');

      // Get the cell contents so we measure correctly. For the header cell we have to account for the sort icon and the menu buttons, if present
      var cells = renderContainerElm.querySelectorAll('.' + uiGridConstants.COL_CLASS_PREFIX + col.uid + ' .ui-grid-cell-contents');
      Array.prototype.forEach.call(cells, function (cell) {
          // Get the cell width
          // gridUtil.logDebug('width', gridUtil.elementWidth(cell));

          // Account for the menu button if it exists
          var menuButton;
          if (angular.element(cell).parent().hasClass('ui-grid-header-cell')) {
            menuButton = angular.element(cell).parent()[0].querySelectorAll('.ui-grid-column-menu-button');
          }

          gridUtil.fakeElement(cell, {}, function(newElm) {
            // Make the element float since it's a div and can expand to fill its container
            var e = angular.element(newElm);
            e.attr('style', 'float: left');

            var width = gridUtil.elementWidth(e);

            if (menuButton) {
              var menuButtonWidth = gridUtil.elementWidth(menuButton);
              width = width + menuButtonWidth;
            }

            if (width > maxWidth) {
              maxWidth = width;
              xDiff = maxWidth - width;
            }
          });
        });

      // check we're not outside the allowable bounds for this column
      col.width = constrainWidth(col, maxWidth);

      // All other columns because fixed to their drawn width, if they aren't already
      resizeAroundColumn(col);

      buildColumnsAndRefresh(xDiff);

      uiGridResizeColumnsService.fireColumnSizeChanged(uiGridCtrl.grid, col.colDef, xDiff);
    });

3

所以,当我需要缩小除了一个之外的所有列时,这个方法对我有用。在网格完成加载后,我遍历所有列,并在调整大小器上触发双击事件。这不是最美观的解决方案,因此如果有其他更好的解决方案,我会非常高兴听到。

function resizeColumn(uid) {
    // document.querySelector might not be supported; if you have jQuery
    // in your project, it might be wise to use that for selecting this
    // element instead
    var resizer = document.querySelector('.ui-grid-col' + uid + ' .ui-grid-column-resizer.right');
    angular.element(resizer).triggerHandler('dblclick');
}

var gridOptions = {
    ...
    onRegisterApi: function (gridApi) {
        // why $interval instead of $timeout? beats me, I'm not smart enough
        // to figure out why, but $timeout repeated infinitely for me
        $interval(function() {
            var columns = gridApi.grid.columns;
            for(var i = 0; i < columns.length; i++) {
                // your conditional here
                if(columns[i].field !== 'name') {
                    resizeColumn(columns[i].uid)
                }
            }
        }, 0, 1);
    }
}

我最终做了与此非常相似的事情,但真的觉得我应该只需使用columnDefs和ui-grid指令就能完成这个任务...你是坚持使用这个解决方案还是设法让它与columnDefs /指令一起工作?我刚刚注意到你几年前发布了这篇文章... - Interesting
我们已经从AngularJS迁移,但我认为这从未改变。 - SnailCoil

2
使用 width : "*",会调整所有可用视口中的列,结果是列被压缩。
指定 minWidth: "somevalue"width: "*" 可以使您的 ui-grid 界面看起来更好。

2

在宽度属性中,你可以使用*作为代替物,它被视为auto。你可以在这里查看更多信息。


1
您可以使用以下代码:
<div ui-grid="gridOptions" class="grid" ui-grid-auto-resize></div>

var app = angular.module('app', ['ui.grid', 'ui.grid.autoResize']);

您可以参考ui-grid文档这里.


此代码调整整个网格的大小,而不是单独的列。 - epol

0

我没有找到任何实现方法,所以这就是我做的:

  1. 迭代前10条记录。

  2. 找到每列数据的最大大小。

  3. 然后动态创建一个 span 标签,并将其包装在该数据中。

  4. 测量标签的宽度,这将是您所需列的近似宽度(可能需要添加一些常量宽度,因为 CSS 的影响等)。

  5. 如果前10条记录为 null,则使用列标题执行相同的过程。


0

我能想到的最好的解决方案是:

  1. 将网格宽度设置为100%
  2. 在您不想调整大小的columnDefs上设置maxWidth属性为一些较小的数字
  3. 让网格自行调整大小

HTML:

ui-grid="gridOptions" class="myuigrid" ui-ui-grid-resize-columns ui-grid-ui-grid-auto-resize></div>

CSS:

.myuigrid {
   width: 100%;
 }

JS

            columnDefs: [
              { name: 'Id', maxWidth:80 },
              { name: 'Name', maxWidth: 280 },
              { name: 'LongName'},
            ],

我知道这种方法并不适用于所有情况,但大多数情况下,您的列都是固定的,而您预先知道的可变列则是需要调整大小的。


“...你不想将大小调整为一些较小的数字” 你是指minWidth吗? - Joshua Drake
@JoshuaDrake 我的想法不是修复它们,而是阻止它们被选择调整大小,以便其他列可以更好地进行调整。 - Rob Sedgwick

0

将以下内容添加到gridoptions中

                    init: function (gridCtrl, gridScope) {
                        gridScope.$on('ngGridEventData', function () {
                            $timeout(function () {
                                angular.forEach(gridScope.columns, function (col) {
                                    gridCtrl.resizeOnData(col);
                                });
                            });
                        });
                    }

确保每个列定义都有任意宽度的数字

width: 100 

没问题。


2
从版本3开始,不再支持init。 - Will Lovett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接