Search code examples
angularelectronmat-tab

mat-tab - click triggers ripple effect but not tab change


In my angular-electron app I use mat-tab-group, in every tab i load the same instance of a component.

I have two ways to create new Tabs: - one by clicking a button in the component which holds the mat-tab-group - the second one is triggered via an IPC message.

Both ways call the same function, where I push a new object to an array, the tabs are created via *ngFor on this array.

The effect:

While the "second" tab created by the clicked button behaves normally, the one triggered via IPC ("third") does not:

The ripple effect is shown right on the click on the "third"-tab, but the click event on the tab (selectedTabChange) is only triggered when i click a second time somewhere in the window. Also, the content of the tab (wrapped in an ng-template) is changed only after the second click.

Both, the component which holds the tabs as well as the one which is instantiated in every tab, use push strategy in change detection.

I am pretty sure that this has something to do with ngZones, but I am not sure how I could solve this problem. Thanks for any help!

Animated Gif here:

switching Tabs

Code HTML:

<mat-icon  (click)="MakeTabActive()">build</mat-icon>

<mat-tab-group mat-align-tabs="start" [selectedIndex]="selectedTab" (selectedTabChange)="RegisterTabChange($event)">
                <mat-tab *ngFor="let item of openWfTabs">
                  <ng-template mat-tab-label>
                      {{item.title}}
                    <mat-icon class="example-tab-icon" (click)="removeTabHandler(item.uid)">close</mat-icon>
                  </ng-template>
                  {{item.uid}}
                  <app-wf-tabcontent [wfContentElementUID]=item.uid>
                  </app-wf-tabcontent>
                </mat-tab>
              </mat-tab-group>

Code TS:

this._electronService.ipcRenderer.on('to-all', (event, arg) => {

  this.MakeTabActive();

});


MakeTabActive(newTab?:any) {
 if (!newTab) {
  newTab = new WfTab();
 }

 if (!this.openWfTabs.includes(newTab)) {
      this.openWfDocumentElements.push(newTab);
 }

    for (let i:number = 0; i<this.openWfTabs.length;i++) {
      if (this.openWfTabs[i].uid == newTab.uid) {
        this.selectedTab = i;
      }
    }
    this.ref.detectChanges();
  }


Solution

  • Wow, that was way easier than I thought:

    Turns out that because of the subscription to the Electron Service, the code ran outside the NgZone and it stayed there.

    I found out because I inserted this in the called function: console.log(NgZone.isInAngularZone());

    The same function returned one time true, one time false on this, depending on how I called it.

    The solution was really straightforward:

    In the subscription to the electron service, I now call the createTab function like this: this.ngZone.run(() => this.createNewTab());