首页 > 解决方案 > 如何在 Angular UI 网格中用鼠标选择一列?

问题描述

例如,在下面非常简单的 Angular UI 网格示例中,您不能选择特定列。单击鼠标并拖动时,它将同时选择行和列,有没有办法只选择一列?

http://embed.plnkr.co/BjLqXGiUI8nQFwvijduh

此外,无论您选择什么,如果您复制并粘贴到 excel 中,数据总是在一列中,格式不正确。有谁知道如何解决这一问题?谢谢!!!

标签: angularjsangular-ui-grid

解决方案


JS:

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

app.controller('MainCtrl', [
  '$scope',
  '$http',
  '$log',
  '$timeout',
  'uiGridConstants',
  function($scope, $http, $log, $timeout, uiGridConstants) {
    $scope.gridOptions = {
      modifierKeysToMultiSelectCells: true,
      enableRowSelection: false,
      enableSelectAll: true,
      // selectionRowHeaderWidth: 35,
      rowHeight: 35,
      showGridFooter: true,
    };

    $scope.gridOptions.columnDefs = [
      { name: 'name' },
      { name: 'amount', displayName: 'Amount', allowCellFocus: false },
    ];

    $scope.gridOptions.multiSelect = true;

    $http.get('data.json').success(function(data) {
      $scope.gridOptions.data = data;
    });

    $scope.info = {};

    $scope.captureCopy = function(e) {
      console.log('captured keyboard event.');
      if ((e.keyCode === 99 || e.keyCode === 67) && e.ctrlKey) {
        console.log('copying...');
      }
    };

    $scope.gridOptions.onRegisterApi = function(gridApi) {
      //set gridApi on scope
      $scope.gridApi = gridApi;
    };
  },
]);

app
  .controller('SecondCtrl', [
    '$scope',
    '$http',
    '$interval',
    'uiGridConstants',
    function($scope, $http, $interval, uiGridConstants) {
      $scope.gridOptions = {
        enableRowSelection: true,
        enableRowHeaderSelection: false,
      };

      $scope.gridOptions.columnDefs = [
        { name: 'id' },
        { name: 'name' },
        {
          name: 'age',
          displayName: 'Age (not focusable)',
          allowCellFocus: false,
        },
        { name: 'address.city' },
      ];

      $scope.gridOptions.multiSelect = false;
      $scope.gridOptions.modifierKeysToMultiSelect = false;
      $scope.gridOptions.noUnselect = true;
      $scope.gridOptions.onRegisterApi = function(gridApi) {
        $scope.gridApi = gridApi;
      };

      $scope.toggleRowSelection = function() {
        $scope.gridApi.selection.clearSelectedRows();
        $scope.gridOptions.enableRowSelection = !$scope.gridOptions
          .enableRowSelection;
        $scope.gridApi.core.notifyDataChange(
          uiGridConstants.dataChange.OPTIONS
        );
      };

      $http.get('data.json').success(function(data) {
        $scope.gridOptions.data = data;

        // $interval whilst we wait for the grid to digest the data we just gave it
        $interval(
          function() {
            $scope.gridApi.selection.selectRow($scope.gridOptions.data[0]);
          },
          0,
          1
        );
      });
    },
  ])
  .directive('uiGridCellSelection', function($compile) {
    /*
  Proof of concept, in reality we need on/off events etc.
  */
    return {
      require: 'uiGrid',
      link: function(scope, element, attrs, uiGridCtrl) {
        // Taken from cellNav
        //add an element with no dimensions that can be used to set focus and capture keystrokes
        var gridApi = uiGridCtrl.grid.api;
        var focuser = $compile(
          '<div class="ui-grid-focuser" tabindex="-1"></div>'
        )(scope);
        element.append(focuser);

        uiGridCtrl.focus = function() {
          focuser[0].focus();
        };

        gridApi.cellNav.on.viewPortKeyDown(scope, function(e) {
          if ((e.keyCode === 99 || e.keyCode === 67) && e.ctrlKey) {
            var cells = gridApi.cellNav.getCurrentSelection();
            var copyString = '',
              rowId = cells[0].row.uid;
            angular.forEach(cells, function(cell) {
              if (cell.row.uid !== rowId) {
                copyString += '\n';
                rowId = cell.row.uid;
              }
              copyString += gridApi.grid
                .getCellValue(cell.row, cell.col)
                .toString();
              copyString += ', ';
            });
            // Yes, this should be build into a directive, but this is a quick and dirty example.
            var textArea = document.getElementById('grid-clipboard');
            textArea.value = copyString;
            textArea = document.getElementById('grid-clipboard').select();
          }
        });
        focuser.on('keyup', function(e) {});
      },
    };
  })
  .directive('uiGridClipboard', function() {
    return {
      template:
        '<textarea id="grid-clipboard" ng-model="uiGridClipBoardContents"></textarea>',
      replace: true,
      link: function(scope, element, attrs) {
        // Obviously this needs to be hidden better (probably a z-index, and positioned behind something opaque)
        element.css('height', '1px');
        element.css('width', '1px');
        element.css('resize', 'none');
      },
    };
  });

HTML:

<!doctype html>
<html ng-app="app">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.js"></script>
    <script src="//cdn.rawgit.com/angular-ui/bower-ui-grid/v3.0.6/ui-grid.min.js"></script>
    <link rel="stylesheet" href="//cdn.rawgit.com/angular-ui/bower-ui-grid/v3.0.6/ui-grid.min.css" type="text/css" />
    <link rel="stylesheet" href="main.css" type="text/css">
  </head>
  <body>

<div ng-controller="MainCtrl" >
  <p>Select using ctrl-click. To select many: press ctrl+click in the cell you want to mark and paste it into MS excel. Note that you must select the cells int the right order, since the cellNav api returns them in the selection order, not the order they appear in the grid.</p>
  <br/>

  <div ui-grid="gridOptions" ui-grid-cell-selection ui-grid-cellNav class="grid"></div>
  <div ui-grid-clipboard ng-keydown="captureCopy($event)"></div>
</div>



    <script src="app.js"></script>
  </body>
</html>

可以复制单元格并粘贴到excel中。你应该能够从中找出你需要的东西。否则我明天可以再快速浏览一下。希望能帮助到你!


推荐阅读