Normally I simply use the gridReady event, get the api and call sizeColumnsToFit().
export class MyGridApplicationComponent {
private gridOptions: GridOptions;
private showGrid2: false;
constructor() {
this.gridOptions = <GridOptions>{
onGridReady: this.gridReady.bind(),
....
};
}
gridReady(params) {
params.api.sizeColumnsToFit();
}
....
However, I have a grid that is in a hidden tab and so when the gridReady event is called, the width is 0 (get the message in the console: "tried to call sizeColumnsToFit() but the grid is coming back with zero width, maybe the grid is not visible yet on the screen?").
<h2>Grid only visible after button click</h2>
<button (click)="showGrid2 = true;">Show grid</button><br/><br/>
<div style="width: 100%;" [hidden]="!showGrid2">
<ag-grid-angular #agGrid2 style="width: 100%; height: 200px;" class="ag-theme-fresh" [gridOptions]="gridOptions">
</ag-grid-angular>
</div>
Is there an event I can hook into when the ag-grid becomes visible so I can resize/fit it? I've tried a few vaguely relevant events (gridSizeChanged, firstDataRendered, columnVisible, columnResized) to no avail.
I have a simplified repro in StackBlitz.
[EDIT] I tried a modification to @antirealm's suggestion below (seeing if *ngIf on the parent div made the difference) and this worked for my (over)simplified version of the problem: see StackBlitz repro.
This is all in context of a nested tabs component, where the ag-grid is not on the first tab. I've tried using *ngIf in the div containing the nested tab content:
<div *ngIf="hasBeenActive" [hidden]="!active"><ng-content></ng-content></div>
and even though the DOM shows that the ag-grid is not there, the ag-grid's gridReady event is still called before the second tab has been selected. See Stackblitz repro.
<div *ngIf="hasBeenShown" style="width: 100%;" [hidden]="!grid2Showing">
<ag-grid-angular #agGrid2 style="width: 100%; height: 200px;" class="ag-theme-fresh" [gridOptions]="gridOptions">
</ag-grid-angular>
</div>
Solutions to actual problem: ag-grid hitting gridReady when projected content (ng-content), in this case in a nested-tab component:
a) (Solution from @antirealm) Make a publicly available 'hasBeenActive' variable on the nested-tab component, and then use it in an *ngIf direct on your ag-grid:
export class NestedTabComponent ... {
...
public hasBeenActive: boolean = false;
activate() {
this.active = true;
this.hasBeenActive = true;
}
....
<nested-tab title="Second grid" #myTab>
<div style="width: 100%;">
<ag-grid-angular *ngIf="myTab.hasBeenActive"
...>
</ag-grid-angular>
</div>
</nested-tab>
b) Modify the nested-tab component to use a template if one exists, then wrap the content of any nested-tab that shouldn't be initialised immediately in a template:
@Component({
selector: 'nested-tab',
template: `
<div *ngIf="hasBeenActive" [hidden]="!active">
<ng-container *ngTemplateOutlet="content"></ng-container>
<ng-content></ng-content>
</div>`
})
export class NestedTabComponent implements OnInit {
@ContentChild(TemplateRef) content;
....
<nested-tab title="Second grid">
<ng-template>
<p>The Second grid rendered:</p>
<div style="width: 100%;">
<ag-grid-angular ...></ag-grid-angular>
</div>
</ng-template>
</nested-tab>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With