Angular md-tab 中的 SlickGrid 动态网格未加载定义

Angular SlickGrid Dynamic grid inside md-tab not loading the definitions

Angular 光滑网格未使用 md-tab 加载

md 标签创建后,子组件将被创建。我在子组件 ts 的 ngOnInit 方法上设置选项卡配置。

我不确定这里缺少什么。

如果选项卡已加载,则会出现 dom 不存在错误。

Parent.html

<mat-tab-group [selectedIndex]="selected.value"  (selectedTabChange)="tabChanged($event)">
    <mat-tab>
        <ng-template mat-tab-label>
            ...
        </ng-template>
        Content 1
        <div class="container col-12" style="width: 100%; height: 100%;">
            <angular-slickgrid gridId="grid1"
                      [columnDefinitions]="columnDefinitions"
                      [gridOptions]="gridOptions"
                      [dataset]="dataset"
                      (sgOnSelectedRowsChanged)="onSelectedRowsChanged($event.detail.eventData, $event.detail.args)"
                      (sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
                      >
            </angular-slickgrid>
          </div>
    </mat-tab>
<mat-tab *ngFor="let tab of tabs; let index = index">
    <ng-template mat-tab-label>
        <div class="d-flex">
            <div class="d-flex">
                ...
            </div>
            <div class="d-flex ml-4">
                <a class="" (click)="removeTab(tab)"> 
                    <span class="fa fa-times fa-1x"></span>
                </a>
            </div>
        </div>
    </ng-template>
    Content of {{tab}}
    <div class="container col-12" style="width: 100%; height: 100%;" [id]="tab" >
        Table : {{tab}}
        <child-details [id]="tab" [query]="tab"></child-details> 
      </div>
</mat-tab>
</mat-tab-group>


父组件

export class ParentComponent implements OnInit, OnDestroy {

  columnDefinitions: Column[] = [];
  gridOptions: GridOption = {};
  dataset: any[] = [];
  angularGrid: AngularGridInstance;

  constructor( private angularUtilService: AngularUtilService,private http: HttpClient) { 
    this.prepareGrid()

  }

  ngOnDestroy(): void {
    sessionStorage.setItem("pinnedTabs", this.tabs.join('|'));
  }

  inputValue: string = "";

  tabs = [];
  selected = new FormControl(0);

  ngOnInit(): void {
    if (sessionStorage.getItem('pinnedTabs') !== null && sessionStorage.getItem('pinnedTabs') !== undefined && sessionStorage.getItem('pinnedTabs').trim() !== "") {
      this.tabs = sessionStorage.getItem('pinnedTabs').split('|');
    }

  }

  removeTab(tabName: string) {
    this.tabs.splice(this.tabs.indexOf(tabName), 1);
    sessionStorage.setItem("pinnedTabs", this.tabs.join('|'));
  }

  addNewTab(tabName: string) {
    console.log("Added new tab")
    if (this.tabs.indexOf(tabName) === -1) {
      this.tabs.push(tabName);
    }
    this.selected.setValue(this.tabs.indexOf(tabName) + 1);
    sessionStorage.setItem("pinnedTabs", this.tabs.join('|'));
  }

  getConfigurations() : Observable<JobListConfig[]>{
    return this.http.get<...[]>('...');
  }


  prepareGrid() {
    this.columnDefinitions = [
      {
        "id": "id", "name": "id", "field": "id", "sortable": true, type: FieldType.number, "filterable": true, "filter": { model: Filters.compoundInputNumber }, formatter(rowIndex, cellIndex, value, columnObject, rowObject, grid) {
          return "<label class='pointer' (click)=addNewTab(" + rowObject.id + ")>" + rowObject.jobId + "</label>";
        }
      }
      .....
    ];

    this.gridOptions = {
      enableAutoResize: true,
      enableSorting: true,
      enablePagination: true,
      enableFiltering: true,
      enableCellNavigation: true,
      datasetIdPropertyName: "id",
      createPreHeaderPanel: true,
      showPreHeaderPanel: true,
      alwaysShowVerticalScroll: false,
      //autoHeight: true,
      autoResize: {
        containerId: 'demo-container',
        sidePadding: 15
      },
      
      pagination: {
        pageSize:10,
        pageSizes:[10,15,20]
      },
      enableCheckboxSelector: true,
      enableRowSelection: true,
      rowSelectionOptions: {
        // True (Single Selection), False (Multiple Selections)
        selectActiveRow: false
      },

      //headerRowHeight: 40,
      //rowHeight: 60
   //   preHeaderPanelHeight: 28,
     // colspanCallback: this.renderDifferentColspan,
    };

    // fill the dataset with your data
    this.dataset = this.mockData();
  }

  onSelectedRowsChanged(e, args) {
    // user clicked on the 1st column, multiple checkbox selection
    console.log('multiple row checkbox selected', event, args);
  }

  onCellClicked(e, args) {
    // when clicking on any cell, we will make it the new selected row
    // however, we don't want to interfere with multiple row selection checkbox which is on 1st column cell

    if(args.cell !== 0 && args.grid.getColumns()[args.cell].id==="id"){
      this.addNewTab(args.grid.getData().getItems()[args.row]["id"])
    }
  }

  mockData() {
    // mock a dataset
    const mockDataset = [];
    for (let i = 0; i < 100; i++) {
      mockDataset[i] = {
        "id": i,
        ....
      };
    }

    return mockDataset;
  }

  tabChanged(event) {
    console.log("Tab changed");
    console.log(event);
  }
}

子模板html

<angular-slickgrid [gridId]="query" [columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions"
   [dataset]="dataset" (onAngularGridCreated)="angularGridReady($event)">
   </angular-slickgrid>
export class ChildCompoent implements OnInit {

  @Input() query: Array<any>;

  private angularGrid: AngularGridInstance;


  ngOnInit(): void {
    console.log("Ng On init")
    console.log(this.query);
    this.prepareGrid();
  }

  constructor(private http: HttpClient) {
   

  }

  columnDefinitions: Column[] = [];
  gridOptions: GridOption = {};
  dataset: any[] = [];

  prepareGrid() {
    this.columnDefinitions = [
      {
        "id": "id", "name": "id", "field": "id", "sortable": true, type: FieldType.number, "filterable": true, "filter": { model: Filters.compoundInputNumber }, formatter(rowIndex, cellIndex, value, columnObject, rowObject, grid) {
          return "<label class='pointer' (click)=addNewTab(" + rowObject.id + ")>" + rowObject.jobId + "</label>";
        }
      }
      ....
      },

    ];

    this.gridOptions = {
      enableAutoResize: true,
      enableSorting: true,
      enablePagination: true,
      enableFiltering: true,
      enableCellNavigation: true,
      datasetIdPropertyName: "id",
      createPreHeaderPanel: true,
      showPreHeaderPanel: true,
      alwaysShowVerticalScroll: false,
      //autoHeight: true,
      autoResize: {
        containerId: 'demo-container',
        sidePadding: 15
      },

      pagination: {
        pageSize: 10,
        pageSizes: [10, 15, 20]
      },
      enableCheckboxSelector: true,
      enableRowSelection: true,
      rowSelectionOptions: {
        // True (Single Selection), False (Multiple Selections)
        selectActiveRow: false
      },

      //headerRowHeight: 40,
      //rowHeight: 60
      //   preHeaderPanelHeight: 28,
      // colspanCallback: this.renderDifferentColspan,
    };

    // fill the dataset with your data
    this.dataset = this.mockData();
  }

  mockData() {
    // mock a dataset
    const mockDataset = [];
    for (let i = 0; i < 100; i++) {

      mockDataset[i] = {
        "id": i,
        ....
      };
    }

    return mockDataset;
  }


  angularGridReady(angularGrid: AngularGridInstance) {
    console.log('slickgrid created');
    this.angularGrid = angularGrid;
  }

  onTabSelected(tab){
    console.log("Tab selected")
    this.angularGrid.resizerService.resizeGrid();
  }
}

示例屏幕截图

提前致谢。

我已经通过如下方式将样式添加到容器并用 <ng-template matTabContent>

包装来解决
    <ng-template matTabContent>
    <child-details class="container col-12" style="width: 100%; height: 100%;" [id]="tab" [query]="tab" ></child-details> 
</ng-template>