@ionic/angular
Version:
Angular specific wrappers for @ionic/core
232 lines • 9.38 kB
JavaScript
import { Injectable, Optional } from '@angular/core';
import { NavigationStart, NavigationCancel, NavigationError, } from '@angular/router';
import * as i0 from "@angular/core";
import * as i1 from "./platform";
import * as i2 from "@angular/common";
import * as i3 from "@angular/router";
export class NavController {
location;
serializer;
router;
topOutlet;
direction = DEFAULT_DIRECTION;
animated = DEFAULT_ANIMATED;
animationBuilder;
guessDirection = 'forward';
guessAnimation;
lastNavId = -1;
constructor(platform, location, serializer, router) {
this.location = location;
this.serializer = serializer;
this.router = router;
// Subscribe to router events to detect direction
if (router) {
router.events.subscribe((ev) => {
if (ev instanceof NavigationStart) {
// restoredState is set if the browser back/forward button is used
const id = ev.restoredState ? ev.restoredState.navigationId : ev.id;
this.guessDirection = this.guessAnimation = id < this.lastNavId ? 'back' : 'forward';
this.lastNavId = this.guessDirection === 'forward' ? ev.id : id;
}
// Reset explicit direction when navigation is canceled (e.g., guard rejection)
// to prevent stale direction from leaking into the next navigation
if (ev instanceof NavigationCancel || ev instanceof NavigationError) {
this.direction = DEFAULT_DIRECTION;
this.animated = DEFAULT_ANIMATED;
this.animationBuilder = undefined;
}
});
}
// Subscribe to backButton events
platform.backButton.subscribeWithPriority(0, (processNextHandler) => {
this.pop();
processNextHandler();
});
}
/**
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
* it's equivalent to calling `this.router.navigateByUrl()`, but it's explicit about the **direction** of the transition.
*
* Going **forward** means that a new page is going to be pushed to the stack of the outlet (ion-router-outlet),
* and that it will show a "forward" animation by default.
*
* Navigating forward can also be triggered in a declarative manner by using the `[routerDirection]` directive:
*
* ```html
* <a routerLink="/path/to/page" routerDirection="forward">Link</a>
* ```
*/
navigateForward(url, options = {}) {
this.setDirection('forward', options.animated, options.animationDirection, options.animation);
return this.navigate(url, options);
}
/**
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
* it's equivalent to calling:
*
* ```ts
* this.navController.setDirection('back');
* this.router.navigateByUrl(path);
* ```
*
* Going **back** means that all the pages in the stack until the navigated page is found will be popped,
* and that it will show a "back" animation by default.
*
* Navigating back can also be triggered in a declarative manner by using the `[routerDirection]` directive:
*
* ```html
* <a routerLink="/path/to/page" routerDirection="back">Link</a>
* ```
*/
navigateBack(url, options = {}) {
this.setDirection('back', options.animated, options.animationDirection, options.animation);
return this.navigate(url, options);
}
/**
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
* it's equivalent to calling:
*
* ```ts
* this.navController.setDirection('root');
* this.router.navigateByUrl(path);
* ```
*
* Going **root** means that all existing pages in the stack will be removed,
* and the navigated page will become the single page in the stack.
*
* Navigating root can also be triggered in a declarative manner by using the `[routerDirection]` directive:
*
* ```html
* <a routerLink="/path/to/page" routerDirection="root">Link</a>
* ```
*/
navigateRoot(url, options = {}) {
this.setDirection('root', options.animated, options.animationDirection, options.animation);
return this.navigate(url, options);
}
/**
* Same as [Location](https://angular.io/api/common/Location)'s back() method.
* It will use the standard `window.history.back()` under the hood, but featuring a `back` animation
* by default.
*/
back(options = { animated: true, animationDirection: 'back' }) {
this.setDirection('back', options.animated, options.animationDirection, options.animation);
return this.location.back();
}
/**
* This methods goes back in the context of Ionic's stack navigation.
*
* It recursively finds the top active `ion-router-outlet` and calls `pop()`.
* This is the recommended way to go back when you are using `ion-router-outlet`.
*
* Resolves to `true` if it was able to pop.
*/
async pop() {
let outlet = this.topOutlet;
while (outlet) {
if (await outlet.pop()) {
return true;
}
else {
outlet = outlet.parentOutlet;
}
}
return false;
}
/**
* This methods specifies the direction of the next navigation performed by the Angular router.
*
* `setDirection()` does not trigger any transition, it just sets some flags to be consumed by `ion-router-outlet`.
*
* It's recommended to use `navigateForward()`, `navigateBack()` and `navigateRoot()` instead of `setDirection()`.
*/
setDirection(direction, animated, animationDirection, animationBuilder) {
this.direction = direction;
this.animated = getAnimation(direction, animated, animationDirection);
this.animationBuilder = animationBuilder;
}
/**
* @internal
*/
setTopOutlet(outlet) {
this.topOutlet = outlet;
}
/**
* @internal
*/
consumeTransition() {
let direction = 'root';
let animation;
const animationBuilder = this.animationBuilder;
if (this.direction === 'auto') {
direction = this.guessDirection;
animation = this.guessAnimation;
}
else {
animation = this.animated;
direction = this.direction;
}
this.direction = DEFAULT_DIRECTION;
this.animated = DEFAULT_ANIMATED;
this.animationBuilder = undefined;
return {
direction,
animation,
animationBuilder,
};
}
navigate(url, options) {
if (Array.isArray(url)) {
return this.router.navigate(url, options);
}
else {
/**
* navigateByUrl ignores any properties that
* would change the url, so things like queryParams
* would be ignored unless we create a url tree
* More Info: https://github.com/angular/angular/issues/18798
*/
const urlTree = this.serializer.parse(url.toString());
if (options.queryParams !== undefined) {
urlTree.queryParams = { ...options.queryParams };
}
if (options.fragment !== undefined) {
urlTree.fragment = options.fragment;
}
/**
* `navigateByUrl` will still apply `NavigationExtras` properties
* that do not modify the url, such as `replaceUrl` which is why
* `options` is passed in here.
*/
return this.router.navigateByUrl(urlTree, options);
}
}
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NavController, deps: [{ token: i1.Platform }, { token: i2.Location }, { token: i3.UrlSerializer }, { token: i3.Router, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NavController, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NavController, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [{ type: i1.Platform }, { type: i2.Location }, { type: i3.UrlSerializer }, { type: i3.Router, decorators: [{
type: Optional
}] }] });
const getAnimation = (direction, animated, animationDirection) => {
if (animated === false) {
return undefined;
}
if (animationDirection !== undefined) {
return animationDirection;
}
if (direction === 'forward' || direction === 'back') {
return direction;
}
else if (direction === 'root' && animated === true) {
return 'forward';
}
return undefined;
};
const DEFAULT_DIRECTION = 'auto';
const DEFAULT_ANIMATED = undefined;
//# sourceMappingURL=nav-controller.js.map