使用 ag-grid,在使用 angular 1.5 和指令时,如何使 `api` 属性不为空?

Using ag-grid, how can I get the `api` attribute to not be null when working with angular 1.5 and directives?

免责声明

首先,我想指出我是 Angular 的新手,所以我可能做错了什么/愚蠢的事情。我终于到了我不确定还能尝试什么的地步。

上下文

我正在做一个项目,我需要一个可以包含嵌套或分组列的网格。该站点也在 AngularJS 1.5.9 中构建。网格的一个特性是能够根据用户的选择隐藏或显示网格中的一组列。此外,在使用 AngularJS 时,我试图坚持使用指令,因为它使组件更容易 use/re-use 跨应用程序。另外,在我看来,它使代码更具可读性。

问题/问题

目前,当用户单击模板上的切换复选框时,gridOptions 对象上的 api 属性未定义。据我所知 documentation on ag-grid says that this attribute should exist once the grid is bound. How do I get this to work properly without abandoning the directive? View the problem on Plunker

我试过的

app.js

(function(){
  var app = angular.module('app', ['agGrid']);
  agGrid.initialiseAgGridWithAngular1(angular);

  app.directive('gridExample', function(){
    return {
      restrict: 'E',
      templateUrl:'sample-grid.html',
      controller: ['$scope', function($scope){
        // Objects
        $scope.options = {
          toggleColumn: true
        };
        // var ctrl = this;

        var rowData = [
          {col1: '1a', col2: '2a', col3: '3a'},
          {col1: '1b', col2: '2b', col3: '3b'},
          {col1: '1c', col2: '2c', col3: '3c'},
        ];

        // Methods
        $scope.loadData = function(){
          var columns = [];

          columns.push({headerName: "Col 1", field: "col1"});

          if ($scope.options.toggleColumn == true) {
            columns.push({headerName: "Col 2", field: "col2"});
          }

          columns.push({headerName: "Col 3", field: "col3"});

          $scope.gridOptions = {
            columnDefs: columns,
            rowData: rowData,
            angularCompileRows: false,
            enableColResize: true
          };
        };

        $scope.refreshGrid = function() {
          $scope.loadData();

          // HERE: I've tried this and $scope
          this.gridOptions.api.refreshView();
        };

        $scope.loadData();
      }]
    };
  });
})();

模板标记

<label>
  <input type="checkbox"
         ng-model="options.toggleColumn"
         ng-click="refreshGrid()" />
         Toggle Col 2
</label>
<div ag-grid="gridOptions" class="ag-blue" style="height: 300px;"></div>

这里的问题是您在第二次调用 loadData 时替换了初始化的 $scope.gridOptions。

快速解决方法是:

if ($scope.gridOptions) {
    $scope.gridOptions.api.setColumnDefs(columns)

} else {
    $scope.gridOptions = {
        columnDefs: columns,
        rowData: rowData,
        angularCompileRows: false,
        enableColResize: true
    };
}

这会设置 gridOptions 一次,第二次就重新使用它。

然而,更好的解决方案是将 gridOptions 设置在将要再次调用的方法之外

在这种情况下,像这样的东西将是一个很好的起点:

// Objects
$scope.options = {
    toggleColumn: true
};

var rowData = [
    {col1: '1a', col2: '2a', col3: '3a'},
    {col1: '1b', col2: '2b', col3: '3b'},
    {col1: '1c', col2: '2c', col3: '3c'},
];

$scope.gridOptions = {
    rowData: rowData,
    angularCompileRows: false,
    enableColResize: true,
    onGridReady: () => {
        $scope.loadData();
    }
};

// Methods
$scope.loadData = function () {
    var columns = [];

    columns.push({headerName: "Col 1", field: "col1"});

    if ($scope.options.toggleColumn == true) {
        columns.push({headerName: "Col 2", field: "col2"});
    }

    columns.push({headerName: "Col 3", field: "col3"});

    $scope.gridOptions.api.setColumnDefs(columns)

};

$scope.refreshGrid = function () {
    $scope.loadData();
    $scope.gridOptions.api.refreshView();
};

现在我们在任何方法之外设置 gridOptions,这将确保它以后不会被覆盖。我们还使用 gridReady 事件在网格准备就绪后加载数据(其他 api 可能还不可用)