javascript - Beräkna om ngx-datatable vid klickhändelse från en annan direktiv


Jag har en sidonavigering med en dockningsfunktion och en datatabell i huvudvyn. Vid undockning av sidonavigeringen omberäknas inte datatabellen i huvudvyn (detta lämnar ett tomt utrymme där sidonavigeringen var), så jag behöver omberäkna manuellt vid klick. Problemet ligger dock i att sidonavigeringen och datatabellen är två olika direktiv.

PS. Jag har flera moduler med olika datatabellnamn

Samma problem här: https://github.com/swimlane/ngx-datatable/issues/193#issuecomment-334809144

Svar #1

Jag gjorde det med MutationObserver som spårar stiländringar för vänstermenyn och sätter DatatableComponent bredd.

@Directive({ selector: '[sidePanelToggle]' })
export class SidePanelToggleDirective implements OnDestroy {
  private changes: MutationObserver;
  wasVisible: boolean | undefined;

  constructor(
    private elementRef: ElementRef,
    @Host() @Self() private tableComponent: DatatableComponent
  ) {
    this.changes = new MutationObserver((mutations: MutationRecord[]) => {
        mutations.forEach((mutation: MutationRecord) => {
            const sideNavElement = mutation.target as HTMLElement;
            const tableElement = this.elementRef.nativeElement as HTMLElement;
            const isVisible = sideNavElement?.style.visibility === 'visible';
            if (this.wasVisible === undefined || this.wasVisible && !isVisible || !this.wasVisible && isVisible) {
              if (tableElement.style.width) {
                tableElement.style.width = `${SidePanelToggleDirective.floatOrZero(tableElement.style.width) + (isVisible ? -sideNavElement.offsetWidth : sideNavElement.offsetWidth)}px`;
                console.log('Already set before, now will be ', tableElement.style.width);
              }
              else {
                tableElement.style.width = `${tableElement.offsetWidth + (isVisible ? -sideNavElement.offsetWidth : sideNavElement.offsetWidth)}px`;
                console.log('Setting first time as ', tableElement.style.width);
              }
              this.tableComponent.recalculate();
            }
            this.wasVisible = isVisible;
        });
    });

    document.querySelectorAll('mat-sidenav[position="start"]').forEach(element => {
      this.changes.observe(element, { attributeFilter: ['style'] });
    });
  }

  private static floatOrZero(value: any) {
    const result = parseFloat(value);
    return isNaN(result) ? 0 : result;
  }

  ngOnDestroy(): void {
    this.changes.disconnect();
  }
}

Förändringen i pålägg är minimal:

<ngx-datatable sidePanelToggle ...