Skip to content

Commit

Permalink
fix(module:tabs): selectedIndex should only be changed by router event
Browse files Browse the repository at this point in the history
  • Loading branch information
yangjunhan committed Dec 31, 2020
1 parent 0694079 commit a1dfde4
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
8 changes: 6 additions & 2 deletions components/tabs/tab-link.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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<HTMLAnchorElement>,
@Optional() @Self() public routerLink?: RouterLink,
@Optional() @Self() public routerLinkWithHref?: RouterLinkWithHref
) {}
}
49 changes: 47 additions & 2 deletions components/tabs/tabset.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,47 @@ xdescribe('NzTabSet router', () => {
});
});

describe('NzTabSet router', () => {
let fixture: ComponentFixture<RouterTabsTestComponent>;
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: `
<nz-tabset
Expand Down Expand Up @@ -1068,7 +1109,7 @@ class DeprecatedAPITabsTestComponent {

@Component({
template: `
<nz-tabset nzLinkRouter>
<nz-tabset nzLinkRouter (nzSelectedIndexChange)="handleSelection($event)">
<nz-tab nzTitle="default">
<a *nzTabLink nz-tab-link [routerLink]="['.']">One</a>
One
Expand All @@ -1081,7 +1122,11 @@ class DeprecatedAPITabsTestComponent {
<router-outlet></router-outlet>
`
})
export class RouterTabsTestComponent {}
export class RouterTabsTestComponent {
handleSelection(_event: number): void {
// noop
}
}

const routes: Routes = [
{
Expand Down
18 changes: 14 additions & 4 deletions components/tabs/tabset.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
>
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit a1dfde4

Please sign in to comment.