diff --git a/angular/src/directives/navigation/router-link-delegate.ts b/angular/src/directives/navigation/router-link-delegate.ts index 31bcf9c8e3..40a2a395a8 100644 --- a/angular/src/directives/navigation/router-link-delegate.ts +++ b/angular/src/directives/navigation/router-link-delegate.ts @@ -12,7 +12,7 @@ import { NavController } from '../../providers/nav-controller'; * animation so that the routing integration will transition correctly. */ @Directive({ - selector: '[routerLink]', + selector: ':not(a):not(area)[routerLink]', }) export class RouterLinkDelegateDirective implements OnInit, OnChanges { @Input() @@ -37,9 +37,56 @@ export class RouterLinkDelegateDirective implements OnInit, OnChanges { this.updateTargetUrlAndHref(); } - @HostListener('click') - onClick(): void { + private updateTargetUrlAndHref() { + if (this.routerLink?.urlTree) { + const href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.routerLink.urlTree)); + this.elementRef.nativeElement.href = href; + } + } + + /** + * @internal + */ + @HostListener('click', ['$event']) + onClick(ev: UIEvent): void { this.navCtrl.setDirection(this.routerDirection, undefined, undefined, this.routerAnimation); + + /** + * This prevents the browser from + * performing a page reload when pressing + * an Ionic component with routerLink. + * The page reload interferes with routing + * and causes ion-back-button to disappear + * since the local history is wiped on reload. + */ + ev.preventDefault(); + } +} + +@Directive({ + selector: 'a[routerLink],area[routerLink]', +}) +export class RouterLinkWithHrefDelegateDirective implements OnInit, OnChanges { + @Input() + routerDirection: RouterDirection = 'forward'; + + @Input() + routerAnimation?: AnimationBuilder; + + constructor( + private locationStrategy: LocationStrategy, + private navCtrl: NavController, + private elementRef: ElementRef, + private router: Router, + @Optional() private routerLink?: RouterLink + ) {} + + ngOnInit(): void { + this.updateTargetUrlAndHref(); + } + + ngOnChanges(): void { + this.updateTargetUrlAndHref(); } private updateTargetUrlAndHref() { @@ -48,4 +95,12 @@ export class RouterLinkDelegateDirective implements OnInit, OnChanges { this.elementRef.nativeElement.href = href; } } + + /** + * @internal + */ + @HostListener('click') + onClick(): void { + this.navCtrl.setDirection(this.routerDirection, undefined, undefined, this.routerAnimation); + } } diff --git a/angular/src/index.ts b/angular/src/index.ts index 12f9f34c9e..1ad3660a2e 100644 --- a/angular/src/index.ts +++ b/angular/src/index.ts @@ -8,7 +8,11 @@ export { IonTabs } from './directives/navigation/ion-tabs'; export { IonBackButtonDelegateDirective as IonBackButtonDelegate } from './directives/navigation/ion-back-button'; export { NavDelegate } from './directives/navigation/nav-delegate'; export { IonRouterOutlet } from './directives/navigation/ion-router-outlet'; -export { RouterLinkDelegateDirective as RouterLinkDelegate } from './directives/navigation/router-link-delegate'; +export { + RouterLinkDelegateDirective as RouterLinkDelegate, + RouterLinkWithHrefDelegateDirective as RouterLinkWithHrefDelegate, +} from './directives/navigation/router-link-delegate'; + export { NavParams } from './directives/navigation/nav-params'; export { IonVirtualScroll } from './directives/virtual-scroll/virtual-scroll'; export { VirtualItem } from './directives/virtual-scroll/virtual-item'; diff --git a/angular/src/ionic-module.ts b/angular/src/ionic-module.ts index 28986acd97..2e58b0ba1c 100644 --- a/angular/src/ionic-module.ts +++ b/angular/src/ionic-module.ts @@ -12,7 +12,10 @@ import { IonBackButtonDelegateDirective } from './directives/navigation/ion-back import { IonRouterOutlet } from './directives/navigation/ion-router-outlet'; import { IonTabs } from './directives/navigation/ion-tabs'; import { NavDelegate } from './directives/navigation/nav-delegate'; -import { RouterLinkDelegateDirective } from './directives/navigation/router-link-delegate'; +import { + RouterLinkDelegateDirective, + RouterLinkWithHrefDelegateDirective, +} from './directives/navigation/router-link-delegate'; import { IonModal } from './directives/overlays/modal'; import { IonPopover } from './directives/overlays/popover'; import { @@ -195,6 +198,7 @@ const DECLARATIONS = [ IonBackButtonDelegateDirective, NavDelegate, RouterLinkDelegateDirective, + RouterLinkWithHrefDelegateDirective, // virtual scroll VirtualFooter,