From 2306e0d61a232e79249e31357f3cbdc769312f2c Mon Sep 17 00:00:00 2001 From: chenc Date: Mon, 21 Feb 2022 19:51:20 +0800 Subject: [PATCH] fix(module:button): prevent default event fire (#7267) * fix(module:button): prevent default event fire * test(module:button): add test case * test(module:button): update test logic * test(module:button): revert test case name * chore(module:button): resolve test case fail --- components/button/button.component.ts | 4 ++-- components/button/button.spec.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/components/button/button.component.ts b/components/button/button.component.ts index 9970f59986..49cef36faa 100644 --- a/components/button/button.component.ts +++ b/components/button/button.component.ts @@ -141,10 +141,10 @@ export class NzButtonComponent implements OnDestroy, OnChanges, AfterViewInit, A // The compiler generates the `ɵɵlistener` instruction which wraps the actual listener internally into the // function, which runs `markDirty()` before running the actual listener (the decorated class method). // Since we're preventing the default behavior and stopping event propagation this doesn't require Angular to run the change detection. - fromEvent(this.elementRef.nativeElement, 'click') + fromEvent(this.elementRef.nativeElement, 'click', { capture: true }) .pipe(takeUntil(this.destroy$)) .subscribe(event => { - if (this.disabled && (event.target as HTMLElement)?.tagName === 'A') { + if ((this.disabled && (event.target as HTMLElement)?.tagName === 'A') || this.nzLoading) { event.preventDefault(); event.stopImmediatePropagation(); } diff --git a/components/button/button.spec.ts b/components/button/button.spec.ts index f34b8317b5..d13566d2b9 100644 --- a/components/button/button.spec.ts +++ b/components/button/button.spec.ts @@ -180,6 +180,17 @@ describe('button', () => { // Previously, it would've caused `tick()` to be called 2 times, because 2 click events have been triggered. expect(spy).toHaveBeenCalledTimes(0); }); + + it('prevent default and stop propagation when the button state is loading', fakeAsync(() => { + testBed.component.nzLoading = true; + testBed.fixture.detectChanges(); + const event = new MouseEvent('click'); + const preventDefaultSpy = spyOn(event, 'preventDefault').and.callThrough(); + const stopImmediatePropagationSpy = spyOn(event, 'stopImmediatePropagation').and.callThrough(); + buttonElement.dispatchEvent(event); + expect(preventDefaultSpy).toHaveBeenCalledTimes(1); + expect(stopImmediatePropagationSpy).toHaveBeenCalledTimes(1); + })); }); }); @@ -281,6 +292,13 @@ export class TestButtonIconOnlyComponent {} }) export class TestButtonIconOnlyLoadingComponent {} +@Component({ + template: ` ` +}) +export class TestButtonWithLoadingComponent { + @Input() nzLoading: boolean = false; +} + @Component({ template: `