@@ -384,4 +384,148 @@ addNewColumn() {
384384 // you could also use SlickGrid setColumns() method
385385 // this.angularGrid.slickGrid.setColumns(cols);
386386}
387+ ` ` `
388+
389+ ## Row Detail with Inner Grid
390+
391+ You can also add an inner grid inside a Row Detail, however there are a few things to know off and remember. Any time a Row Detail is falling outside the main grid viewport, it will be unmounted and until it comes back into the viewport which is then remounted. The process of unmounting and remounting means that Row Detail previous states aren't preserved, however you could use Grid State & Presets to overcome this problem.
392+
393+ ##### Component
394+
395+ Main Grid Component
396+
397+ ` ` ` ts
398+ import { Component , OnInit , ViewEncapsulation } from ' @angular/core' ;
399+ import { AngularGridInstance , Column , GridOption , GridState } from ' angular-slickgrid' ;
400+
401+ @Component ({
402+ styleUrls: [' main-grid.component.scss' ],
403+ templateUrl: ' ./main-grid.component.html' ,
404+ encapsulation: ViewEncapsulation .None ,
405+ })
406+ export class MainGridComponent implements OnInit {
407+ columnDefinitions: Column [] = [];
408+ gridOptions! : GridOption ;
409+ angularGrid! : AngularGridInstance ;
410+ dataset: Distributor [] = [];
411+ showSubTitle = true ;
412+
413+ get rowDetailInstance(): SlickRowDetailView {
414+ return this .angularGrid .extensions .rowDetailView ?.instance || {};
415+ }
416+
417+ angularGridReady(angularGrid : AngularGridInstance ) {
418+ this .angularGrid = angularGrid ;
419+ }
420+
421+ ngOnInit(): void {
422+ this .defineGrid ();
423+ this .dataset = this .getData ();
424+ }
425+
426+ defineGrid() {
427+ this .columnDefinitions = [ /* ...*/ ];
428+ this .gridOptions = {
429+ enableRowDetailView: true ,
430+ rowSelectionOptions: {
431+ selectActiveRow: true
432+ },
433+ preRegisterExternalExtensions : (pubSubService ) => {
434+ // Row Detail View is a special case because of its requirement to create extra column definition dynamically
435+ // so it must be pre-registered before SlickGrid is instantiated, we can do so via this option
436+ const rowDetail = new SlickRowDetailView (pubSubService as EventPubSubService );
437+ return [{ name: ExtensionName .rowDetailView , instance: rowDetail }];
438+ },
439+ rowDetailView: {
440+ process : (item : any ) => simulateServerAsyncCall (item ),
441+ loadOnce: false , // IMPORTANT, you can't use loadOnce with inner grid because only HTML template are re-rendered, not JS events
442+ panelRows: 10 ,
443+ preloadComponent: PreloadComponent ,
444+ viewComponent: InnerGridComponent ,
445+ },
446+ };
447+ }
448+ }
449+ ` ` `
450+
451+ Now, let's define our Inner Grid Component
452+
453+ ` ` ` html
454+ < div [class ]= " innerGridClass" >
455+ <h4 >Order Details (id : {{ model .id }})< / h4 >
456+ < div class = " container-fluid" >
457+ < angular - slickgrid
458+ [gridId ]= " innerGridId"
459+ [columnDefinitions ]= " innerColDefs"
460+ [gridOptions ]= " innerGridOptions"
461+ [dataset ]= " innerDataset"
462+ (onAngularGridCreated )= " angularGridReady($event.detail)"
463+ >
464+ < / angular - slickgrid >
465+ < / div >
466+ < / div >
467+ ` ` `
468+
469+ ` ` ` ts
470+ import { Component , OnInit , ViewEncapsulation } from ' @angular/core' ;
471+ import { AngularGridInstance , Column , GridOption , GridState } from ' angular-slickgrid' ;
472+
473+ export interface Distributor { /* ... */ }
474+ export interface OrderData { /* ... */ }
475+
476+ @Component ({
477+ templateUrl: ' ./inner-grid.component.html' ,
478+ })
479+ export class InnerGridComponent implements OnInit {
480+ model! : Distributor ;
481+ innerColDefs: Column [] = [];
482+ innerGridOptions! : GridOption ;
483+ angularGrid! : AngularGridInstance ;
484+ innerDataset: any [] = [];
485+ innerGridId = ' ' ;
486+ innerGridClass = ' ' ;
487+
488+ ngOnInit(): void {
489+ this .innerGridId = ` innergrid-${this .model .id } ` ;
490+ this .innerGridClass = ` row-detail-${this .model .id } ` ;
491+ this .defineGrid ();
492+ this .innerDataset = [... this .model .orderData ];
493+ }
494+
495+ angularGridReady(angularGrid : AngularGridInstance ) {
496+ this .angularGrid = angularGrid ;
497+ }
498+
499+ defineGrid() {
500+ // OPTIONALLY reapply Grid State as Presets before unmounting the compoment
501+ let gridState: GridState | undefined ;
502+ const gridStateStr = sessionStorage .getItem (` gridstate_${this .innerGridClass } ` );
503+ if (gridStateStr ) {
504+ gridState = JSON .parse (gridStateStr );
505+ }
506+
507+ this .innerColDefs = [
508+ { id: ' orderId' , field: ' orderId' , name: ' Order ID' , filterable: true , sortable: true },
509+ { id: ' shipCity' , field: ' shipCity' , name: ' Ship City' , filterable: true , sortable: true },
510+ { id: ' freight' , field: ' freight' , name: ' Freight' , filterable: true , sortable: true , type: ' number' },
511+ { id: ' shipName' , field: ' shipName' , name: ' Ship Name' , filterable: true , sortable: true },
512+ ];
513+
514+ this .innerGridOptions = {
515+ autoResize: {
516+ container: ` .${this .innerGridClass } ` ,
517+ },
518+ enableFiltering: true ,
519+ enableSorting: true ,
520+ datasetIdPropertyName: ' orderId' ,
521+ presets: gridState , // reapply grid state presets
522+ };
523+ }
524+
525+ // OPTIONALLY save Grid State before unmounting the compoment
526+ handleBeforeGridDestroy() {
527+ const gridState = this .angularGrid .gridStateService .getCurrentGridState ();
528+ sessionStorage .setItem (` gridstate_${this .innerGridClass } ` , JSON .stringify (gridState ));
529+ }
530+ }
387531` ` `
0 commit comments