Skip to content

Commit bb48232

Browse files
authored
feat(module:pageheader): disable back button if no history (#9041)
* feat(module:pageheader): hide back button if no history * refactor(module:pageheader): remove condition in condition
1 parent 2d9ff5f commit bb48232

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

components/page-header/page-header.component.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ import {
1313
ContentChild,
1414
ElementRef,
1515
EventEmitter,
16+
inject,
1617
Input,
1718
OnDestroy,
1819
OnInit,
1920
Output,
2021
TemplateRef,
21-
ViewEncapsulation,
22-
inject
22+
ViewEncapsulation
2323
} from '@angular/core';
2424
import { Subject } from 'rxjs';
2525
import { map, takeUntil } from 'rxjs/operators';
2626

2727
import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer';
2828
import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
29-
import { PREFIX } from 'ng-zorro-antd/core/logger';
3029
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
30+
import { NzSafeAny } from 'ng-zorro-antd/core/types';
3131
import { NzIconModule } from 'ng-zorro-antd/icon';
3232

3333
import { NzPageHeaderBreadcrumbDirective, NzPageHeaderFooterDirective } from './page-header-cells';
@@ -43,7 +43,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'pageHeader';
4343
<div class="ant-page-header-heading">
4444
<div class="ant-page-header-heading-left">
4545
<!--back-->
46-
@if (nzBackIcon !== null) {
46+
@if (nzBackIcon !== null && enableBackButton) {
4747
<div (click)="onBack()" class="ant-page-header-back">
4848
<div role="button" tabindex="0" class="ant-page-header-back-button">
4949
<ng-container *nzStringTemplateOutlet="nzBackIcon; let backIcon">
@@ -94,6 +94,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'pageHeader';
9494
imports: [NzOutletModule, NzIconModule]
9595
})
9696
export class NzPageHeaderComponent implements AfterViewInit, OnDestroy, OnInit {
97+
private location = inject(Location);
9798
readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME;
9899

99100
@Input() nzBackIcon: string | TemplateRef<void> | null = null;
@@ -111,7 +112,7 @@ export class NzPageHeaderComponent implements AfterViewInit, OnDestroy, OnInit {
111112
destroy$ = new Subject<void>();
112113
dir: Direction = 'ltr';
113114

114-
private location = inject(Location, { optional: true });
115+
enableBackButton = true;
115116

116117
constructor(
117118
public nzConfigService: NzConfigService,
@@ -126,11 +127,18 @@ export class NzPageHeaderComponent implements AfterViewInit, OnDestroy, OnInit {
126127
this.dir = direction;
127128
this.cdr.detectChanges();
128129
});
129-
130130
this.dir = this.directionality.value;
131131
}
132132

133133
ngAfterViewInit(): void {
134+
if (!this.nzBack.observed) {
135+
this.enableBackButton = (this.location.getState() as NzSafeAny)?.navigationId > 1;
136+
this.location.subscribe(() => {
137+
this.enableBackButton = true;
138+
this.cdr.detectChanges();
139+
});
140+
}
141+
134142
this.nzResizeObserver
135143
.observe(this.elementRef)
136144
.pipe(
@@ -147,11 +155,6 @@ export class NzPageHeaderComponent implements AfterViewInit, OnDestroy, OnInit {
147155
if (this.nzBack.observers.length) {
148156
this.nzBack.emit();
149157
} else {
150-
if (!this.location) {
151-
throw new Error(
152-
`${PREFIX} you should import 'RouterModule' or register 'Location' if you want to use 'nzBack' default event!`
153-
);
154-
}
155158
this.location.back();
156159
}
157160
}

components/page-header/page-header.spec.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { BidiModule, Dir, Direction } from '@angular/cdk/bidi';
77
import { Location } from '@angular/common';
88
import { Component, DebugElement, ViewChild } from '@angular/core';
9-
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
9+
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
1010
import { By } from '@angular/platform-browser';
1111
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
1212

@@ -27,6 +27,7 @@ describe('NzPageHeaderComponent', () => {
2727
providers: [provideNzIconsTesting()]
2828
});
2929
location = TestBed.inject(Location);
30+
spyOn(location, 'getState').and.returnValue({ navigationId: 2 });
3031
}));
3132

3233
it('should basic work', () => {
@@ -39,6 +40,14 @@ describe('NzPageHeaderComponent', () => {
3940
expect(pageHeader.nativeElement.querySelector('.ant-page-header-heading-sub-title')).toBeTruthy();
4041
});
4142

43+
it('should displayed the back button if nzBack has observer', () => {
44+
const fixture = TestBed.createComponent(NzDemoPageHeaderBasicComponent);
45+
const pageHeader = fixture.debugElement.query(By.directive(NzPageHeaderComponent));
46+
fixture.detectChanges();
47+
const back = pageHeader.nativeElement.querySelector('.ant-page-header-back-button');
48+
expect(back).toBeTruthy();
49+
});
50+
4251
it('should ghost work', () => {
4352
const fixture = TestBed.createComponent(NzDemoPageHeaderGhostComponent);
4453
const pageHeader = fixture.debugElement.query(By.directive(NzPageHeaderComponent));
@@ -67,6 +76,29 @@ describe('NzPageHeaderComponent', () => {
6776
expect(location.back).toHaveBeenCalled();
6877
});
6978

79+
it('should not show the back button if there is no history of navigation', fakeAsync(() => {
80+
const fixture = TestBed.createComponent(NzDemoPageHeaderResponsiveComponent);
81+
const pageHeader = fixture.debugElement.query(By.directive(NzPageHeaderComponent));
82+
spyOn(location, 'getState').and.returnValue({ navigationId: 1 });
83+
fixture.detectChanges();
84+
pageHeader.componentInstance.ngAfterViewInit();
85+
tick();
86+
fixture.detectChanges();
87+
const back = pageHeader.nativeElement.querySelector('.ant-page-header-back-button');
88+
expect(back).toBeNull();
89+
}));
90+
91+
it('should show the back button if there is history of navigation', fakeAsync(() => {
92+
const fixture = TestBed.createComponent(NzDemoPageHeaderResponsiveComponent);
93+
const pageHeader = fixture.debugElement.query(By.directive(NzPageHeaderComponent));
94+
fixture.detectChanges();
95+
pageHeader.componentInstance.ngAfterViewInit();
96+
tick();
97+
fixture.detectChanges();
98+
const back = pageHeader.nativeElement.querySelector('.ant-page-header-back-button');
99+
expect(back as HTMLDivElement).toBeTruthy();
100+
}));
101+
70102
it('should content work', () => {
71103
const fixture = TestBed.createComponent(NzDemoPageHeaderContentComponent);
72104
const pageHeader = fixture.debugElement.query(By.directive(NzPageHeaderComponent));

0 commit comments

Comments
 (0)