Skip to content

Commit bbfb8f8

Browse files
authored
fix(angular): ionTabsWillChange is fired before tab activation (#27991)
Issue number: Resolves #27212 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> `ionTabsWillChange` emits _after_ the tab view is activated in the stack. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - `ionTabsWillChange` emits _before_ the tab view is activated in the stack. ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev-build: `7.2.4-dev.11692040948.1fd0ecd2`
1 parent 1015c06 commit bbfb8f8

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

packages/angular/src/directives/navigation/ion-router-outlet.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { Config } from '../../providers/config';
3030
import { NavController } from '../../providers/nav-controller';
3131

3232
import { StackController } from './stack-controller';
33-
import { RouteView, getUrl } from './stack-utils';
33+
import { RouteView, StackDidChangeEvent, StackWillChangeEvent, getUrl, isTabSwitch } from './stack-utils';
3434

3535
// TODO(FW-2827): types
3636

@@ -66,7 +66,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
6666
*/
6767
@Input() name = PRIMARY_OUTLET;
6868

69-
@Output() stackEvents = new EventEmitter<any>();
69+
/** @internal */
70+
@Output() stackWillChange = new EventEmitter<StackWillChangeEvent>();
71+
/** @internal */
72+
@Output() stackDidChange = new EventEmitter<StackDidChangeEvent>();
73+
7074
// eslint-disable-next-line @angular-eslint/no-output-rename
7175
@Output('activate') activateEvents = new EventEmitter<any>();
7276
// eslint-disable-next-line @angular-eslint/no-output-rename
@@ -304,9 +308,16 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
304308
*/
305309
this.navCtrl.setTopOutlet(this);
306310

311+
const leavingView = this.stackCtrl.getActiveView();
312+
313+
this.stackWillChange.emit({
314+
enteringView,
315+
tabSwitch: isTabSwitch(enteringView, leavingView),
316+
});
317+
307318
this.stackCtrl.setActive(enteringView).then((data) => {
308319
this.activateEvents.emit(cmpRef.instance);
309-
this.stackEvents.emit(data);
320+
this.stackDidChange.emit(data);
310321
});
311322
}
312323

packages/angular/src/directives/navigation/ion-tabs.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@ import { NavController } from '../../providers/nav-controller';
1616
import { IonTabBar } from '../proxies';
1717

1818
import { IonRouterOutlet } from './ion-router-outlet';
19-
import { StackEvent } from './stack-utils';
19+
import { StackDidChangeEvent, StackWillChangeEvent } from './stack-utils';
2020

2121
@Component({
2222
selector: 'ion-tabs',
2323
template: `
2424
<ng-content select="[slot=top]"></ng-content>
2525
<div class="tabs-inner" #tabsInner>
26-
<ion-router-outlet #outlet tabs="true" (stackEvents)="onPageSelected($event)"></ion-router-outlet>
26+
<ion-router-outlet
27+
#outlet
28+
tabs="true"
29+
(stackWillChange)="onStackWillChange($event)"
30+
(stackDidChange)="onStackDidChange($event)"
31+
></ion-router-outlet>
2732
</div>
2833
<ng-content></ng-content>
2934
`,
@@ -62,7 +67,13 @@ export class IonTabs implements AfterContentInit, AfterContentChecked {
6267
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
6368
@ContentChildren(IonTabBar) tabBars: QueryList<IonTabBar>;
6469

70+
/**
71+
* Emitted before the tab view is changed.
72+
*/
6573
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
74+
/**
75+
* Emitted after the tab view is changed.
76+
*/
6677
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();
6778

6879
private tabBarSlot = 'bottom';
@@ -80,10 +91,19 @@ export class IonTabs implements AfterContentInit, AfterContentChecked {
8091
/**
8192
* @internal
8293
*/
83-
onPageSelected(detail: StackEvent): void {
84-
const stackId = detail.enteringView.stackId;
85-
if (detail.tabSwitch && stackId !== undefined) {
94+
onStackWillChange({ enteringView, tabSwitch }: StackWillChangeEvent): void {
95+
const stackId = enteringView.stackId;
96+
if (tabSwitch && stackId !== undefined) {
8697
this.ionTabsWillChange.emit({ tab: stackId });
98+
}
99+
}
100+
101+
/**
102+
* @internal
103+
*/
104+
onStackDidChange({ enteringView, tabSwitch }: StackDidChangeEvent): void {
105+
const stackId = enteringView.stackId;
106+
if (tabSwitch && stackId !== undefined) {
87107
if (this.tabBar) {
88108
this.tabBar.selectedTab = stackId;
89109
}

packages/angular/src/directives/navigation/stack-controller.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { NavController } from '../../providers/nav-controller';
88

99
import {
1010
RouteView,
11-
StackEvent,
11+
StackDidChangeEvent,
1212
computeStackId,
1313
destroyView,
1414
getUrl,
@@ -61,7 +61,7 @@ export class StackController {
6161
return view;
6262
}
6363

64-
setActive(enteringView: RouteView): Promise<StackEvent> {
64+
setActive(enteringView: RouteView): Promise<StackDidChangeEvent> {
6565
const consumeResult = this.navCtrl.consumeTransition();
6666
let { direction, animation, animationBuilder } = consumeResult;
6767
const leavingView = this.activeView;
@@ -224,6 +224,13 @@ export class StackController {
224224
return this.activeView ? this.activeView.stackId : undefined;
225225
}
226226

227+
/**
228+
* @internal
229+
*/
230+
getActiveView(): RouteView | undefined {
231+
return this.activeView;
232+
}
233+
227234
hasRunningTask(): boolean {
228235
return this.runningTask !== undefined;
229236
}

packages/angular/src/directives/navigation/stack-utils.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,23 @@ export const destroyView = (view: RouteView | undefined): void => {
7979
}
8080
};
8181

82-
export interface StackEvent {
82+
export interface StackWillChangeEvent {
83+
enteringView: RouteView;
84+
/**
85+
* `true` if the event is trigged as a result of a switch
86+
* between tab navigation stacks.
87+
*/
88+
tabSwitch: boolean;
89+
}
90+
91+
export interface StackDidChangeEvent {
8392
enteringView: RouteView;
8493
direction: RouterDirection;
8594
animation: NavDirection | undefined;
95+
/**
96+
* `true` if the event is trigged as a result of a switch
97+
* between tab navigation stacks.
98+
*/
8699
tabSwitch: boolean;
87100
}
88101

0 commit comments

Comments
 (0)