Как автоматически увеличить ширину столбца в AngularJS ui-grid

В AngularJS ui-grid, как я могу настроить сетку так, чтобы она могла автоматически регулировать ширину столбцов в соответствии с содержимым при рендеринге?

Я знаю, что есть учебник, показывающий функцию автоматического размера, но это работает только при двойном щелчке по столбцу, я бы хотел, чтобы это произошло, когда была запущена сетка.

Ответы

Ответ 1

Я не думаю, что эта функция существует на данный момент. Директива uiGridColumnResizer регистрирует прослушиватели событий на dblclick, mousedown и mouseup. Событие dblclick в основном проходит через все выделенные ячейки и вычисляет максимальную ширину и устанавливает ее как ширину столбца. Это будет проблемой производительности, если у вас много строк.

Я бы, вероятно, просто установил максимально возможную ширину, основанную на данных, которые будет иметь сетка.

Или попробуйте воспроизвести поведение в uiGridColumnResizer.

 $elm.on('dblclick', function(event, args) {
      event.stopPropagation();

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

      // Don't resize if it 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 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);
    });

Ответ 2

используйте звездочку в определении столбца:

width:"*";

Ответ 4

вы можете использовать * как в свойстве width, - считать auto вы можете увидеть здесь

Ответ 5

Итак, это сработало для меня, когда мне нужно было сжать все столбцы, кроме одного. Я повторяю все столбцы после завершения загрузки сетки и запускаю событие двойного щелчка на resizer. Не самый красивый, поэтому, если у кого-нибудь еще есть лучшее решение, я был бы очень рад его услышать!

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

Ответ 6

Используя width: "*", настройте все столбцы в доступном порт представления, что приведет к сжатию столбцов.

Указание minWidth: "somevalue" и width: "*" делает вашу ui-сетку лучше выглядеть

Ответ 7

добавьте следующее в gridoptions

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

Убедитесь, что у каждого столбца есть ширина любого случайного числа

width: 100 

Это хорошо.

Ответ 8

Я не нашел никакой реализации для этого, так что это то, что я сделал

  1. Итерируется через первые 10 записей.

  2. Найден максимальный размер данных для каждого столбца.

  3. Затем создал тег span на лету и завернул его этими данными.

  4. Измеряли ширину тега, и это была бы ваша приблизительная ширина, необходимая для столбца (возможно, потребуется добавить некоторую более постоянную ширину из-за эффекта CSS и т.д.).

  5. Если первые 10 записей являются null выполните один и тот же процесс, но на этот раз с заголовком столбца.

Ответ 9

Лучшее решение, которое я могу придумать, это:

  1. установите ширину сетки на 100%
  2. установите атрибут 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'},
            ],

Я знаю, что это не будет работать в каждом случае, но в то же время большинство ваших столбцов более или менее фиксировано, а переменные, которые вы знаете заранее, - это те, которые позволяют изменять размер.

Ответ 10

Я нашел некоторые проблемы с решением ширины. Мы должны использовать свойство cellClass в объекте ui-grid columns для включения этого класса.

.ui-grid-cell-contents-auto {
     /* Old Solution */
    /*min-width: max-content !important;*/

    /* New Solution */
    display: grid;
    grid-auto-columns: max-content;

    /* IE Solution */
    display: -ms-grid;
    -ms-grid-columns: max-content;
}

то вы должны использовать свойство cellClass в объекте столбцов ui-grid для включения этого класса в свою сетку (что-то вроде этого):

columns: [{ field: 'search_name', displayName: '', cellClass: 'ui-grid-cell-contents-auto'}]

Вы можете обратиться к подробному описанию ответа Нехалы. https://github.com/angular-ui/ui-grid/issues/3913