mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 01:52:19 +08:00
fix(nav): insertPages method correctly inserts multiple pages with props (#21725)
fixes #21724
This commit is contained in:
@ -46,4 +46,4 @@ export { IonicModule } from './ionic-module';
|
||||
export { IonicSafeString, getPlatforms, isPlatform, createAnimation } from '@ionic/core';
|
||||
|
||||
// CORE TYPES
|
||||
export { Animation, AnimationBuilder, AnimationCallbackOptions, AnimationDirection, AnimationFill, AnimationKeyFrames, AnimationLifecycle, Gesture, GestureConfig, GestureDetail, mdTransitionAnimation, iosTransitionAnimation } from '@ionic/core';
|
||||
export { Animation, AnimationBuilder, AnimationCallbackOptions, AnimationDirection, AnimationFill, AnimationKeyFrames, AnimationLifecycle, Gesture, GestureConfig, GestureDetail, mdTransitionAnimation, iosTransitionAnimation, NavComponentWithProps } from '@ionic/core';
|
||||
|
@ -745,13 +745,13 @@ ion-nav,method,getActive,getActive() => Promise<ViewController | undefined>
|
||||
ion-nav,method,getByIndex,getByIndex(index: number) => Promise<ViewController | undefined>
|
||||
ion-nav,method,getPrevious,getPrevious(view?: ViewController | undefined) => Promise<ViewController | undefined>
|
||||
ion-nav,method,insert,insert<T extends NavComponent>(insertIndex: number, component: T, componentProps?: ComponentProps<T> | null | undefined, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,insertPages,insertPages(insertIndex: number, insertComponents: NavComponent[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,insertPages,insertPages(insertIndex: number, insertComponents: NavComponent[] | NavComponentWithProps[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,pop,pop(opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,popTo,popTo(indexOrViewCtrl: number | ViewController, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,popToRoot,popToRoot(opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,push,push<T extends NavComponent>(component: T, componentProps?: ComponentProps<T> | null | undefined, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,removeIndex,removeIndex(startIndex: number, removeCount?: number, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,setPages,setPages(views: any[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,setPages,setPages(views: NavComponent[] | NavComponentWithProps[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,method,setRoot,setRoot<T extends NavComponent>(component: T, componentProps?: ComponentProps<T> | null | undefined, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>
|
||||
ion-nav,event,ionNavDidChange,void,false
|
||||
ion-nav,event,ionNavWillChange,void,false
|
||||
|
6
core/src/components.d.ts
vendored
6
core/src/components.d.ts
vendored
@ -5,7 +5,7 @@
|
||||
* It contains typing information for all components that exist in this project.
|
||||
*/
|
||||
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
|
||||
import { ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimeOptions, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, MenuChangeEventDetail, NavComponent, NavOptions, OverlayEventDetail, PickerButton, PickerColumn, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, ViewController } from "./interface";
|
||||
import { ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimeOptions, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, MenuChangeEventDetail, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerButton, PickerColumn, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, ViewController } from "./interface";
|
||||
import { IonicSafeString } from "./utils/sanitization";
|
||||
import { NavigationHookCallback } from "./components/route/route-interface";
|
||||
import { SelectCompareFn } from "./components/select/select-interface";
|
||||
@ -1413,7 +1413,7 @@ export namespace Components {
|
||||
* @param opts The navigation options.
|
||||
* @param done The transition complete function.
|
||||
*/
|
||||
"insertPages": (insertIndex: number, insertComponents: NavComponent[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>;
|
||||
"insertPages": (insertIndex: number, insertComponents: NavComponent[] | NavComponentWithProps[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>;
|
||||
/**
|
||||
* Pop a component off of the navigation stack. Navigates back from the current component.
|
||||
* @param opts The navigation options.
|
||||
@ -1463,7 +1463,7 @@ export namespace Components {
|
||||
* @param opts The navigation options.
|
||||
* @param done The transition complete function.
|
||||
*/
|
||||
"setPages": (views: any[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>;
|
||||
"setPages": (views: NavComponent[] | NavComponentWithProps[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>;
|
||||
/**
|
||||
* Set the root for the current navigation stack to a component.
|
||||
* @param component The component to set as the root of the navigation stack.
|
||||
|
@ -1,10 +1,14 @@
|
||||
import { Animation, AnimationBuilder, ComponentRef, FrameworkDelegate, Mode } from '../../interface';
|
||||
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Mode } from '../../interface';
|
||||
|
||||
import { ViewController } from './view-controller';
|
||||
|
||||
export type NavDirection = 'back' | 'forward';
|
||||
|
||||
export type NavComponent = ComponentRef | ViewController;
|
||||
export interface NavComponentWithProps<T = any> {
|
||||
component: NavComponent;
|
||||
componentProps?: ComponentProps<T> | null;
|
||||
}
|
||||
|
||||
export interface NavResult {
|
||||
hasCompleted: boolean;
|
||||
|
@ -2,7 +2,7 @@ import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch, h
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { Animation, AnimationBuilder, ComponentProps, FrameworkDelegate, Gesture, NavComponent, NavOptions, NavOutlet, NavResult, RouteID, RouteWrite, RouterDirection, TransitionDoneFn, TransitionInstruction, ViewController } from '../../interface';
|
||||
import { Animation, AnimationBuilder, ComponentProps, FrameworkDelegate, Gesture, NavComponent, NavComponentWithProps, NavOptions, NavOutlet, NavResult, RouteID, RouteWrite, RouterDirection, TransitionDoneFn, TransitionInstruction, ViewController } from '../../interface';
|
||||
import { getTimeGivenProgression } from '../../utils/animation/cubic-bezier';
|
||||
import { assert } from '../../utils/helpers';
|
||||
import { TransitionOptions, lifecycle, setPageHidden, transition } from '../../utils/transition';
|
||||
@ -156,7 +156,7 @@ export class Nav implements NavOutlet {
|
||||
return this.queueTrns(
|
||||
{
|
||||
insertStart: -1,
|
||||
insertViews: [{ page: component, params: componentProps }],
|
||||
insertViews: [{ component, componentProps }],
|
||||
opts
|
||||
},
|
||||
done
|
||||
@ -184,7 +184,7 @@ export class Nav implements NavOutlet {
|
||||
return this.queueTrns(
|
||||
{
|
||||
insertStart: insertIndex,
|
||||
insertViews: [{ page: component, params: componentProps }],
|
||||
insertViews: [{ component, componentProps }],
|
||||
opts
|
||||
},
|
||||
done
|
||||
@ -204,7 +204,7 @@ export class Nav implements NavOutlet {
|
||||
@Method()
|
||||
insertPages(
|
||||
insertIndex: number,
|
||||
insertComponents: NavComponent[],
|
||||
insertComponents: NavComponent[] | NavComponentWithProps[],
|
||||
opts?: NavOptions | null,
|
||||
done?: TransitionDoneFn
|
||||
): Promise<boolean> {
|
||||
@ -326,7 +326,7 @@ export class Nav implements NavOutlet {
|
||||
done?: TransitionDoneFn
|
||||
): Promise<boolean> {
|
||||
return this.setPages(
|
||||
[{ page: component, params: componentProps }],
|
||||
[{ component, componentProps }],
|
||||
opts,
|
||||
done
|
||||
);
|
||||
@ -344,7 +344,7 @@ export class Nav implements NavOutlet {
|
||||
*/
|
||||
@Method()
|
||||
setPages(
|
||||
views: any[],
|
||||
views: NavComponent[] | NavComponentWithProps[],
|
||||
opts?: NavOptions | null,
|
||||
done?: TransitionDoneFn
|
||||
): Promise<boolean> {
|
||||
@ -958,7 +958,17 @@ export class Nav implements NavOutlet {
|
||||
|
||||
for (let i = views.length - 1; i >= 0; i--) {
|
||||
const view = views[i];
|
||||
|
||||
/**
|
||||
* When inserting multiple views via insertPages
|
||||
* the last page will be transitioned to, but the
|
||||
* others will not be. As a result, a DOM element
|
||||
* will only be created for the last page inserted.
|
||||
* As a result, it is possible to have views in the
|
||||
* stack that do not have `view.element` yet.
|
||||
*/
|
||||
const element = view.element;
|
||||
if (element) {
|
||||
if (i > activeViewIndex) {
|
||||
// this view comes after the active view
|
||||
// let's unload it
|
||||
@ -971,6 +981,7 @@ export class Nav implements NavOutlet {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private canStart(): boolean {
|
||||
return (
|
||||
|
@ -80,7 +80,7 @@ Type: `Promise<boolean>`
|
||||
|
||||
|
||||
|
||||
### `insertPages(insertIndex: number, insertComponents: NavComponent[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>`
|
||||
### `insertPages(insertIndex: number, insertComponents: NavComponent[] | NavComponentWithProps[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>`
|
||||
|
||||
Inserts an array of components into the navigation stack at the specified index.
|
||||
The last component in the array will become instantiated as a view, and animate
|
||||
@ -145,7 +145,7 @@ Type: `Promise<boolean>`
|
||||
|
||||
|
||||
|
||||
### `setPages(views: any[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>`
|
||||
### `setPages(views: NavComponent[] | NavComponentWithProps[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise<boolean>`
|
||||
|
||||
Set the views of the current navigation stack and navigate to the last view.
|
||||
By default animations are disabled, but they can be enabled by passing options
|
||||
|
@ -818,8 +818,8 @@ describe('NavController', () => {
|
||||
const view5 = mockView(MockView5);
|
||||
|
||||
await nav.setPages([
|
||||
{ page: view4 },
|
||||
{ page: view5 }
|
||||
{ component: view4 },
|
||||
{ component: view5 }
|
||||
], null, trnsDone);
|
||||
expect(instance1.ionViewWillUnload).toHaveBeenCalled();
|
||||
expect(instance2.ionViewWillUnload).toHaveBeenCalled();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AnimationBuilder, ComponentProps, FrameworkDelegate } from '../../interface';
|
||||
import { AnimationBuilder, ComponentProps, FrameworkDelegate, NavComponentWithProps } from '../../interface';
|
||||
import { attachComponent } from '../../utils/framework-delegate';
|
||||
import { assert } from '../../utils/helpers';
|
||||
|
||||
@ -89,13 +89,20 @@ export const convertToView = (page: any, params: ComponentProps | undefined): Vi
|
||||
return new ViewController(page, params);
|
||||
};
|
||||
|
||||
export const convertToViews = (pages: any[]): ViewController[] => {
|
||||
export const convertToViews = (pages: NavComponentWithProps[]): ViewController[] => {
|
||||
return pages.map(page => {
|
||||
if (page instanceof ViewController) {
|
||||
return page;
|
||||
}
|
||||
if ('page' in page) {
|
||||
return convertToView(page.page, page.params);
|
||||
if ('component' in page) {
|
||||
/**
|
||||
* TODO Ionic 6:
|
||||
* Consider switching to just using `undefined` here
|
||||
* as well as on the public interfaces and on
|
||||
* `NavComponentWithProps`. Previously `pages` was
|
||||
* of type `any[]` so TypeScript did not catch this.
|
||||
*/
|
||||
return convertToView(page.component, (page.componentProps === null) ? undefined : page.componentProps);
|
||||
}
|
||||
return convertToView(page, undefined);
|
||||
}).filter(v => v !== null) as ViewController[];
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { defineCustomElements } from '@ionic/core/loader';
|
||||
import { addIcons } from 'ionicons';
|
||||
import { arrowBackSharp, caretBackSharp, chevronBack, chevronForward, close, closeCircle, closeSharp, menuOutline, menuSharp, reorderThreeOutline, reorderTwoSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
||||
export { createAnimation, createGesture, AlertButton, AlertInput, Gesture, GestureConfig, GestureDetail, iosTransitionAnimation, IonicSafeString, mdTransitionAnimation, setupConfig } from '@ionic/core';
|
||||
export { createAnimation, createGesture, AlertButton, AlertInput, Gesture, GestureConfig, GestureDetail, iosTransitionAnimation, IonicSafeString, mdTransitionAnimation, NavComponentWithProps, setupConfig } from '@ionic/core';
|
||||
export * from './proxies';
|
||||
|
||||
// createControllerComponent
|
||||
|
Reference in New Issue
Block a user