Disclaimer
First, I'd like to note I'm completely new to Angular so I am probably doing something wrong / dumb. I have finally come to the point where I'm not sure what else to try.
Context
I an working on a project where I need to have a grid that can contain nested or grouped columns. The site is also being built in AngularJS 1.5.9. One of the features of the grid is to be able to hide or show a set of columns in the grid based on user selections. Also, in using AngularJS I am trying to stick with directives as it makes the components a bit easier to use/re-use across the application. Also, in my opinion, it makes the code much more readable.
Problem / Question
Currently, when the user clicks the toggle checkbox on the template, the api
attribute on the gridOptions
object is undefined. As far as I can tell from the 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
What I've tried
- Using
$scope
directly - Using a variable to store the
this
reference - Understanding / adapting things from this angular 2 example or this SO question
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();
}]
};
});
})();
Template Markup
<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>
The problem here is that you're replacing your initialised $scope.gridOptions in loadData the second time you call it.
A quick fix would be:
This would set the gridOptions once, and the second time around just reuse it.
A better solution however would be to set the gridOptions outside of methods that are going to be called again.
In this case something like this would be a good starting point:
Now we set gridOptions outside of any method, which will ensure it doesn't get overwritten later. We also use the gridReady event to loadData once the grid is ready (other the api might not yet be available to you)