diff --git a/components/tabs/tab-link.directive.ts b/components/tabs/tab-link.directive.ts index 499bdeef5f2..187d36302e2 100644 --- a/components/tabs/tab-link.directive.ts +++ b/components/tabs/tab-link.directive.ts @@ -3,7 +3,7 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ -import { Directive, Host, Optional, Self, TemplateRef } from '@angular/core'; +import { Directive, ElementRef, Host, Optional, Self, TemplateRef } from '@angular/core'; import { RouterLink, RouterLinkWithHref } from '@angular/router'; import { TabTemplateContext } from './interfaces'; @@ -27,5 +27,9 @@ export class NzTabLinkTemplateDirective { exportAs: 'nzTabLink' }) export class NzTabLinkDirective { - constructor(@Optional() @Self() public routerLink?: RouterLink, @Optional() @Self() public routerLinkWithHref?: RouterLinkWithHref) {} + constructor( + public elementRef: ElementRef, + @Optional() @Self() public routerLink?: RouterLink, + @Optional() @Self() public routerLinkWithHref?: RouterLinkWithHref + ) {} } diff --git a/components/tabs/tabset.component.spec.ts b/components/tabs/tabset.component.spec.ts index 460892fb869..5bc91594943 100644 --- a/components/tabs/tabset.component.spec.ts +++ b/components/tabs/tabset.component.spec.ts @@ -851,6 +851,47 @@ xdescribe('NzTabSet router', () => { }); }); +describe('NzTabSet router', () => { + let fixture: ComponentFixture; + let tabs: DebugElement; + let router: Router; + describe('basic', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [CommonModule, NzTabsModule, RouterTestingModule.withRoutes(routes)], + declarations: [RouterTabsTestComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(RouterTabsTestComponent); + fixture.detectChanges(); + + tabs = fixture.debugElement.query(By.directive(NzTabSetComponent)); + }); + + it('should change router and emit handleSelection once when click', fakeAsync(() => { + fixture.ngZone!.run(() => { + router = TestBed.inject(Router); + router.initialNavigation(); + const component = fixture.componentInstance; + spyOn(component, 'handleSelection'); + fixture.detectChanges(); + + expect((tabs.componentInstance as NzTabSetComponent).nzSelectedIndex).toBe(0); + expect(component.handleSelection).toHaveBeenCalledTimes(0); + + // select the second tab + const tabLabel = fixture.debugElement.queryAll(By.css('.ant-tabs-tab'))[1]; + tabLabel.nativeElement.click(); + fixture.detectChanges(); + flush(); + + expect((tabs.componentInstance as NzTabSetComponent).nzSelectedIndex).toBe(1); + expect(component.handleSelection).toHaveBeenCalledTimes(1); + }); + })); + }); +}); + @Component({ template: ` + One One @@ -1081,7 +1122,11 @@ class DeprecatedAPITabsTestComponent { ` }) -export class RouterTabsTestComponent {} +export class RouterTabsTestComponent { + handleSelection(_event: number): void { + // noop + } +} const routes: Routes = [ { diff --git a/components/tabs/tabset.component.ts b/components/tabs/tabset.component.ts index 1f568a88619..e1dcc777f41 100644 --- a/components/tabs/tabset.component.ts +++ b/components/tabs/tabset.component.ts @@ -84,7 +84,7 @@ let nextId = 0; [style.margin-bottom.px]="position === 'vertical' ? nzTabBarGutter : null" [class.ant-tabs-tab-active]="nzSelectedIndex === i" [class.ant-tabs-tab-disabled]="tab.nzDisabled" - (click)="clickNavItem(tab, i)" + (click)="clickNavItem(tab, i, $event)" (contextmenu)="contextmenuNavItem(tab, $event)" *ngFor="let tab of tabs; let i = index" > @@ -383,11 +383,22 @@ export class NzTabSetComponent implements OnInit, AfterContentChecked, OnDestroy } } - clickNavItem(tab: NzTabComponent, index: number): void { + clickNavItem(tab: NzTabComponent, index: number, e: MouseEvent): void { if (!tab.nzDisabled) { // ignore nzCanDeactivate tab.nzClick.emit(); - this.setSelectedIndex(index); + if (!this.isRouterLinkClickEvent(index, e)) { + this.setSelectedIndex(index); + } + } + } + + private isRouterLinkClickEvent(index: number, event: MouseEvent): boolean { + const target = event.target as HTMLElement; + if (this.nzLinkRouter) { + return !!this.tabs.toArray()[index]?.linkDirective?.elementRef.nativeElement.contains(target); + } else { + return false; } } @@ -444,7 +455,6 @@ export class NzTabSetComponent implements OnInit, AfterContentChecked, OnDestroy const index = this.findShouldActiveTabIndex(); if (index !== this.selectedIndex) { this.setSelectedIndex(index); - this.nzSelectedIndexChange.emit(index); } this.nzHideAll = index === -1; }